├── src └── away3dlite │ ├── arcane.as │ ├── loaders │ ├── data │ │ ├── BoneData.as │ │ ├── MeshMaterialData.as │ │ ├── ChannelData.as │ │ ├── FaceData.as │ │ ├── MeshData.as │ │ ├── ObjectData.as │ │ ├── ContainerData.as │ │ ├── AnimationData.as │ │ ├── GeometryData.as │ │ └── MaterialData.as │ ├── utils │ │ ├── TextureLoader.as │ │ ├── AnimationLibrary.as │ │ ├── GeometryLibrary.as │ │ ├── ChannelLibrary.as │ │ ├── MaterialLibrary.as │ │ └── TextureLoadQueue.as │ └── MD2.as │ ├── sprites │ ├── AlignmentType.as │ └── Sprite3D.as │ ├── core │ ├── base │ │ └── SortType.as │ ├── utils │ │ ├── Debug.as │ │ └── Cast.as │ ├── clip │ │ └── RectangleClipping.as │ └── render │ │ ├── FastRenderer.as │ │ ├── BasicRenderer.as │ │ └── Renderer.as │ ├── templates │ ├── BasicTemplate.as │ ├── FastTemplate.as │ └── Template.as │ ├── cameras │ ├── lenses │ │ ├── OrthogonalLens.as │ │ ├── AbstractLens.as │ │ ├── PerspectiveLens.as │ │ └── ZoomFocusLens.as │ ├── TargetCamera3D.as │ ├── Camera3D.as │ └── HoverCamera3D.as │ ├── lights │ ├── AbstractLight3D.as │ ├── PointLight3D.as │ └── DirectionalLight3D.as │ ├── animators │ ├── frames │ │ └── Frame.as │ ├── bones │ │ ├── SkinVertex.as │ │ ├── SkinController.as │ │ ├── Channel.as │ │ └── Bone.as │ ├── MovieMesh.as │ └── BonesAnimator.as │ ├── events │ ├── Loader3DEvent.as │ ├── ClippingEvent.as │ ├── ParserEvent.as │ ├── MaterialEvent.as │ └── MouseEvent3D.as │ ├── materials │ ├── WireframeMaterial.as │ ├── ColorMaterial.as │ ├── BitmapMaterial.as │ ├── WireColorMaterial.as │ ├── BitmapFileMaterial.as │ ├── Material.as │ ├── MovieMaterial.as │ └── Dot3BitmapMaterial.as │ ├── primitives │ ├── AbstractPrimitive.as │ ├── LineSegment.as │ ├── Trident.as │ ├── RegularPolygon.as │ ├── Skybox6.as │ ├── Plane.as │ ├── Torus.as │ ├── Sphere.as │ └── Cone.as │ └── containers │ └── Scene3D.as ├── pbj └── normalMapping.pbj └── pbk └── normalMapping.pbk /src/away3dlite/arcane.as: -------------------------------------------------------------------------------- 1 | package away3dlite 2 | { 3 | public namespace arcane; 4 | } 5 | -------------------------------------------------------------------------------- /pbj/normalMapping.pbj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/away3d/away3dlite-core-fp10/HEAD/pbj/normalMapping.pbj -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/BoneData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { 3 | import flash.geom.*; 4 | 5 | /** 6 | * Data class for a bone used in SkinAnimation. 7 | */ 8 | public class BoneData extends ContainerData 9 | { 10 | /** 11 | * Transform information for the joint in a SkinAnimation 12 | */ 13 | public var jointTransform:Matrix3D = new Matrix3D(); 14 | } 15 | } -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/MeshMaterialData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { 3 | /** 4 | * Data class for teh material of a 3d object 5 | */ 6 | public class MeshMaterialData 7 | { 8 | /** 9 | * The name of the material used as a unique reference for the mesh. 10 | */ 11 | public var symbol:String; 12 | 13 | /** 14 | * A list of faces which are to be drawn with the material. 15 | */ 16 | public var faceList:Array = []; 17 | } 18 | } -------------------------------------------------------------------------------- /src/away3dlite/sprites/AlignmentType.as: -------------------------------------------------------------------------------- 1 | package away3dlite.sprites 2 | { 3 | 4 | /** 5 | * Holds the accepted values for the alignment property in the Sprite3D class. 6 | * 7 | * @see away3dlite.sprites.Sprite3D#alignment 8 | */ 9 | public class AlignmentType 10 | { 11 | /** 12 | * Aligns the sprite parallel to the plane of the viewport. 13 | */ 14 | public static const VIEWPLANE:String = "viewplane"; 15 | 16 | /** 17 | * Aligns the sprite so that it faces the camera object. 18 | */ 19 | public static const VIEWPOINT:String = "viewpoint"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/ChannelData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { 3 | import away3dlite.animators.bones.Channel; 4 | 5 | /** 6 | * Data class for an animation channel 7 | */ 8 | public class ChannelData 9 | { 10 | /** 11 | * The name of the channel used as a unique reference. 12 | */ 13 | public var name:String; 14 | 15 | /** 16 | * The channel object. 17 | */ 18 | public var channel:Channel; 19 | 20 | public var type:String; 21 | 22 | /** 23 | * The xml object 24 | */ 25 | public var xml:XML; 26 | 27 | /** 28 | * The index of the channel inside the XML structure (in case there's more than 1 channel) 29 | */ 30 | public var channelIndex:int; 31 | } 32 | } -------------------------------------------------------------------------------- /src/away3dlite/core/base/SortType.as: -------------------------------------------------------------------------------- 1 | package away3dlite.core.base 2 | { 3 | 4 | /** 5 | * Holds the accepted values for the sortType property in the Mesh class. 6 | * 7 | * @see away3dlite.core.base.Mesh 8 | */ 9 | public class SortType 10 | { 11 | /** 12 | * Sorts the faces in the mesh using their center z-depth ie. the average between all vertices. 13 | */ 14 | public static const CENTER:String = "center"; 15 | 16 | /** 17 | * Sorts the faces in the mesh using their nearest vertex z-depth. 18 | */ 19 | public static const FRONT:String = "front"; 20 | 21 | /** 22 | * Sorts the faces in the mesh using their furthest vertex z-depth. 23 | */ 24 | public static const BACK:String = "back"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/away3dlite/loaders/utils/TextureLoader.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.utils 2 | { 3 | import flash.display.Loader; 4 | import flash.net.URLRequest; 5 | import flash.system.LoaderContext; 6 | 7 | /** 8 | * Used to store the name and loader reference of an external texture image. 9 | */ 10 | public class TextureLoader extends Loader 11 | { 12 | public function TextureLoader() 13 | { 14 | super(); 15 | } 16 | 17 | private var _filename:String; 18 | 19 | public function get filename():String 20 | { 21 | return _filename; 22 | } 23 | 24 | override public function load(request:URLRequest, context:LoaderContext=null):void 25 | { 26 | _filename = request.url; 27 | super.load(request, context); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/away3dlite/templates/BasicTemplate.as: -------------------------------------------------------------------------------- 1 | package away3dlite.templates 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.clip.*; 5 | import away3dlite.core.render.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * Template setup designed for general use. 11 | */ 12 | public class BasicTemplate extends Template 13 | { 14 | /** @private */ 15 | arcane override function init():void 16 | { 17 | super.init(); 18 | 19 | view.renderer = renderer; 20 | view.clipping = clipping; 21 | } 22 | 23 | /** 24 | * The renderer object used in the template. 25 | */ 26 | public var renderer:BasicRenderer = new BasicRenderer(); 27 | 28 | /** 29 | * The clipping object used in the template. 30 | */ 31 | public var clipping:RectangleClipping = new RectangleClipping(); 32 | } 33 | } -------------------------------------------------------------------------------- /src/away3dlite/templates/FastTemplate.as: -------------------------------------------------------------------------------- 1 | package away3dlite.templates 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.clip.*; 5 | import away3dlite.core.render.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * Template setup designed for speed. 11 | */ 12 | public class FastTemplate extends Template 13 | { 14 | /** @private */ 15 | arcane override function init():void 16 | { 17 | super.init(); 18 | 19 | view.renderer = renderer; 20 | view.clipping = clipping; 21 | view.mouseEnabled3D = false; 22 | } 23 | 24 | /** 25 | * The renderer object used in the template. 26 | */ 27 | public var renderer:FastRenderer = new FastRenderer(); 28 | 29 | /** 30 | * The clipping object used in the template. 31 | */ 32 | public var clipping:Clipping = new Clipping(); 33 | } 34 | } -------------------------------------------------------------------------------- /src/away3dlite/cameras/lenses/OrthogonalLens.as: -------------------------------------------------------------------------------- 1 | package away3dlite.cameras.lenses 2 | { 3 | import away3dlite.arcane; 4 | 5 | import flash.geom.*; 6 | 7 | use namespace arcane; 8 | 9 | public class OrthogonalLens extends AbstractLens 10 | { 11 | /** @private */ 12 | override arcane function _update():void 13 | { 14 | _view = _camera._view; 15 | _scale = _camera.zoom / _camera.focus; 16 | _projectionMatrix3D.identity(); 17 | _projectionMatrix3D.appendScale(_scale, _scale, 1); 18 | } 19 | 20 | private var _scale:Number; 21 | 22 | public function OrthogonalLens() 23 | { 24 | super(); 25 | } 26 | 27 | public override function unProject(x:Number, y:Number, z:Number):Vector3D 28 | { 29 | var scale:Number = _camera.focus/_camera.zoom; 30 | return new Vector3D(x*scale, y*scale, z*scale); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/away3dlite/cameras/lenses/AbstractLens.as: -------------------------------------------------------------------------------- 1 | package away3dlite.cameras.lenses 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.cameras.*; 5 | import away3dlite.containers.*; 6 | 7 | import flash.display.*; 8 | import flash.geom.*; 9 | 10 | use namespace arcane; 11 | 12 | public class AbstractLens 13 | { 14 | /** @private */ 15 | arcane var _view:View3D; 16 | /** @private */ 17 | arcane var _root:DisplayObject; 18 | /** @private */ 19 | arcane var _camera:Camera3D; 20 | /** @private */ 21 | arcane var _projectionMatrix3D:Matrix3D = new Matrix3D(); 22 | /** @private */ 23 | arcane function _update():void 24 | { 25 | 26 | } 27 | 28 | public function AbstractLens() 29 | { 30 | } 31 | 32 | public function unProject(x:Number, y:Number, z:Number):Vector3D 33 | { 34 | return new Vector3D(x, y, z); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/FaceData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { 3 | /** 4 | * Data class for a face object. 5 | */ 6 | public class FaceData 7 | { 8 | /** 9 | * Index of vertex 0. 10 | */ 11 | public var v0:int; 12 | 13 | /** 14 | * Index of vertex 1. 15 | */ 16 | public var v1:int; 17 | 18 | /** 19 | * Index of vertex 2. 20 | */ 21 | public var v2:int; 22 | 23 | /** 24 | * Index of uv coordinate 0. 25 | */ 26 | public var uv0:int; 27 | 28 | /** 29 | * Index of uv coordinate 1. 30 | */ 31 | public var uv1:int; 32 | 33 | /** 34 | * Index of uv coordinate 2. 35 | */ 36 | public var uv2:int; 37 | 38 | /** 39 | * Determines whether the face is visible. 40 | */ 41 | public var visible:Boolean; 42 | 43 | /** 44 | * Holds teh material data for the face. 45 | */ 46 | public var materialData:MaterialData; 47 | } 48 | } -------------------------------------------------------------------------------- /src/away3dlite/cameras/lenses/PerspectiveLens.as: -------------------------------------------------------------------------------- 1 | package away3dlite.cameras.lenses 2 | { 3 | import away3dlite.arcane; 4 | 5 | import flash.geom.*; 6 | 7 | use namespace arcane; 8 | 9 | public class PerspectiveLens extends AbstractLens 10 | { 11 | /** @private */ 12 | override arcane function _update():void 13 | { 14 | _view = _camera._view; 15 | _root = _view.root; 16 | _projection = _root.transform.perspectiveProjection; 17 | 18 | _projection.focalLength = _camera.zoom*_camera.focus; 19 | 20 | _projectionMatrix3D = _projection.toMatrix3D(); 21 | } 22 | 23 | private var _projection:PerspectiveProjection; 24 | 25 | public function PerspectiveLens() 26 | { 27 | super(); 28 | } 29 | 30 | public override function unProject(x:Number, y:Number, z:Number):Vector3D 31 | { 32 | var persp:Number = z/(_camera.zoom*_camera.focus); 33 | return new Vector3D(x*persp, y*persp, z); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/MeshData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { 3 | /** 4 | * Data class for the mesh data of a 3d object 5 | */ 6 | public class MeshData extends ObjectData 7 | { 8 | public var material:MaterialData; 9 | /** 10 | * Defines the geometry used by the mesh instance 11 | */ 12 | public var geometry:GeometryData; 13 | 14 | /** 15 | * 16 | */ 17 | public var skeleton:String; 18 | 19 | /** 20 | * Duplicates the mesh data's properties to another MeshData object 21 | * 22 | * @param object The new object instance into which all properties are copied 23 | * @return The new object instance with duplicated properties applied 24 | */ 25 | public override function clone(object:ObjectData):void 26 | { 27 | super.clone(object); 28 | 29 | var mesh:MeshData = (object as MeshData); 30 | 31 | mesh.material = material; 32 | mesh.geometry = geometry; 33 | mesh.skeleton = skeleton; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/away3dlite/lights/AbstractLight3D.as: -------------------------------------------------------------------------------- 1 | package away3dlite.lights 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.cameras.*; 5 | 6 | use namespace arcane; 7 | 8 | /** 9 | * @author robbateman 10 | */ 11 | public class AbstractLight3D 12 | { 13 | private var _color:uint; 14 | /** @private */ 15 | arcane var _red:Number; 16 | /** @private */ 17 | arcane var _green:Number; 18 | /** @private */ 19 | arcane var _blue:Number; 20 | /** @private */ 21 | arcane var _camera:Camera3D; 22 | 23 | /** 24 | * 25 | */ 26 | public function get color():uint 27 | { 28 | return _color; 29 | } 30 | 31 | public function set color(val:uint):void 32 | { 33 | if (_color == val) 34 | return; 35 | 36 | _color = val; 37 | 38 | _red = ((_color & 0xFF0000) >> 16)/255; 39 | _green = ((_color & 0xFF00) >> 8)/255; 40 | _blue = (_color & 0xFF)/255; 41 | } 42 | 43 | /** 44 | * 45 | */ 46 | public function AbstractLight3D() 47 | { 48 | 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/ObjectData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { 3 | import flash.geom.*; 4 | /** 5 | * Data class for a generic 3d object 6 | */ 7 | public class ObjectData 8 | { 9 | /** 10 | * The name of the 3d object used as a unique reference. 11 | */ 12 | public var name:String; 13 | 14 | /** 15 | * The 3d transformation matrix for the 3d object 16 | */ 17 | public var transform:Matrix3D = new Matrix3D(); 18 | 19 | /** 20 | * Collada animation id 21 | */ 22 | public var id:String; 23 | 24 | //public var scale:Number; 25 | 26 | /** 27 | * Duplicates the object data's properties to another ObjectData object 28 | * 29 | * @param object The new object instance into which all properties are copied 30 | * @return The new object instance with duplicated properties applied 31 | */ 32 | public function clone(object:ObjectData):void 33 | { 34 | object.name = name; 35 | object.transform = transform; 36 | object.id = id; 37 | //dst.scale = scale; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/away3dlite/animators/frames/Frame.as: -------------------------------------------------------------------------------- 1 | package away3dlite.animators.frames 2 | { 3 | /** 4 | * Stores a set of vertices representing the position of a mesh for a sigle frame of an animation. 5 | * 6 | * @see away3dlite.animators.MovieMesh 7 | */ 8 | public class Frame 9 | { 10 | /** 11 | * The name of the frame. 12 | */ 13 | public var name:String; 14 | 15 | /** 16 | * The array of vertices contained inside the frame 17 | */ 18 | public var vertices:Vector.; 19 | 20 | /** 21 | * Creates a new Frame object with a name and a set of vertices 22 | * 23 | * @param name The name of the frame. 24 | * @param vertices An array of Vertex objects. 25 | */ 26 | public function Frame(name:String, vertices:Vector.) 27 | { 28 | this.name = name; 29 | this.vertices = vertices; 30 | } 31 | 32 | /** 33 | * Returns a string representation of the Frame object 34 | */ 35 | public function toString():String 36 | { 37 | return "[Frame][name:" + name + "][vertices:" + vertices.length + "]"; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/away3dlite/loaders/utils/AnimationLibrary.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.utils { import away3dlite.core.utils.Debug; import away3dlite.loaders.data.*; import flash.utils.Dictionary; /** * Store for all animations associated with an externally loaded file. */ public dynamic class AnimationLibrary extends Dictionary { /** * Adds an animation name reference to the library. */ public function addAnimation(name:String):AnimationData { //return if animation already exists if (this[name]) return this[name]; var animationData:AnimationData = new AnimationData(); this[animationData.name = name] = animationData; return animationData; } /** * Returns an animation data object for the given name reference in the library. */ public function getAnimation(name:String):AnimationData { //return if animation exists if (this[name]) return this[name]; Debug.warning("Animation '" + name + "' does not exist"); return null; } } } -------------------------------------------------------------------------------- /src/away3dlite/cameras/lenses/ZoomFocusLens.as: -------------------------------------------------------------------------------- 1 | package away3dlite.cameras.lenses 2 | { 3 | import away3dlite.arcane; 4 | 5 | import flash.geom.*; 6 | 7 | use namespace arcane; 8 | 9 | public class ZoomFocusLens extends AbstractLens 10 | { 11 | /** @private */ 12 | override arcane function _update():void 13 | { 14 | _view = _camera._view; 15 | _root = _view.root; 16 | _projection = _root.transform.perspectiveProjection; 17 | 18 | _projection.focalLength = _camera.zoom*_camera.focus; 19 | 20 | _projectionMatrix3D = _projection.toMatrix3D(); 21 | _projectionMatrix3D.appendTranslation(0, 0, _camera.focus); 22 | 23 | _projectionData = _projectionMatrix3D.rawData; 24 | _projectionData[15] = _projectionData[14]; 25 | _projectionMatrix3D.rawData = _projectionData; 26 | } 27 | 28 | private var _projection:PerspectiveProjection; 29 | private var _projectionData:Vector.; 30 | 31 | public function ZoomFocusLens() 32 | { 33 | super(); 34 | } 35 | 36 | public override function unProject(x:Number, y:Number, z:Number):Vector3D 37 | { 38 | var persp:Number = z/(_camera.zoom*_camera.focus); 39 | return new Vector3D(x*persp, y*persp, z - _camera.focus); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/ContainerData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { 3 | import away3dlite.containers.ObjectContainer3D; 4 | /** 5 | * Data class for 3d object containers. 6 | */ 7 | public class ContainerData extends MeshData 8 | { 9 | /** 10 | * An array containing the child 3d objects of the container. 11 | */ 12 | public var children:Array = []; 13 | 14 | /** 15 | * Reference to the 3d container object of the resulting container. 16 | */ 17 | public var container:ObjectContainer3D; 18 | 19 | /** 20 | * Returns the maximum x value of the container data 21 | */ 22 | public var maxX:Number; 23 | 24 | /** 25 | * Returns the minimum x value of the container data 26 | */ 27 | public var minX:Number; 28 | 29 | /** 30 | * Returns the maximum y value of the container data 31 | */ 32 | public var maxY:Number; 33 | 34 | /** 35 | * Returns the minimum y value of the container data 36 | */ 37 | public var minY:Number; 38 | 39 | /** 40 | * Returns the maximum z value of the container data 41 | */ 42 | public var maxZ:Number; 43 | 44 | /** 45 | * Returns the minimum z value of the container data 46 | */ 47 | public var minZ:Number; 48 | } 49 | } -------------------------------------------------------------------------------- /src/away3dlite/cameras/TargetCamera3D.as: -------------------------------------------------------------------------------- 1 | package away3dlite.cameras 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.cameras.lenses.*; 5 | import away3dlite.core.base.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * Extended camera used to automatically look at a specified target object. 11 | * 12 | * @see away3dlite.containers.View3D 13 | */ 14 | public class TargetCamera3D extends Camera3D 15 | { 16 | /** @private */ 17 | arcane override function update():void 18 | { 19 | if (target != null) 20 | lookAt(target.transform.matrix3D.position); 21 | 22 | super.update(); 23 | } 24 | 25 | /** 26 | * The 3d object targeted by the camera. 27 | */ 28 | public var target:Object3D; 29 | 30 | /** 31 | * Creates a new TargetCamera3D object. 32 | * 33 | * @param focus Defines the distance from the focal point of the camera to the viewing plane. 34 | * @param zoom Defines the overall scale value of the view. 35 | * @param target The 3d object targeted by the camera. 36 | */ 37 | public function TargetCamera3D(focus:Number = 10, zoom:Number = 100, target:Object3D = null, lens:AbstractLens = null) 38 | { 39 | super(focus, zoom, lens); 40 | 41 | this.target = target || new Object3D(); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/away3dlite/events/Loader3DEvent.as: -------------------------------------------------------------------------------- 1 | package away3dlite.events { import away3dlite.loaders.*; import flash.events.Event; /** * Passed as a parameter when a 3d object loader event occurs */ public class Loader3DEvent extends Event { /** * Defines the value of the type property of a loadSuccess event object. */ public static const LOAD_SUCCESS:String = "loadSuccess"; /** * Defines the value of the type property of a loadProgress event object. */ public static const LOAD_PROGRESS:String = "loadProgress"; /** * Defines the value of the type property of a loadError event object. */ public static const LOAD_ERROR:String = "loadError"; /** * A reference to the loader object that is relevant to the event. */ public var loader:Loader3D; /** * Creates a new Loader3DEvent object. * * @param type The type of the event. Possible values are: Loader3DEvent.LOAD_SUCCESS and Loader3DEvent.LOAD_ERROR. * @param loader A reference to the loader object that is relevant to the event. */ public function Loader3DEvent(type:String, loader:Loader3D) { super(type); this.loader = loader; } /** * Creates a copy of the Loader3DEvent object and sets the value of each property to match that of the original. */ public override function clone():Event { return new Loader3DEvent(type, loader); } } } -------------------------------------------------------------------------------- /src/away3dlite/events/ClippingEvent.as: -------------------------------------------------------------------------------- 1 | package away3dlite.events 2 | { 3 | import away3dlite.core.clip.*; 4 | 5 | import flash.events.Event; 6 | 7 | /** 8 | * Passed as a parameter when a clip event occurs 9 | */ 10 | public class ClippingEvent extends Event 11 | { 12 | /** 13 | * Defines the value of the type property of a ClipingUpdated event object. 14 | */ 15 | public static const CLIPPING_UPDATED:String = "clippingUpdated"; 16 | 17 | /** 18 | * Defines the value of the type property of a ScreenUpdated event object. 19 | */ 20 | public static const SCREEN_UPDATED:String = "screenUpdated"; 21 | 22 | /** 23 | * A reference to the session object that is relevant to the event. 24 | */ 25 | public var clipping:Clipping; 26 | 27 | /** 28 | * Creates a new FaceEvent object. 29 | * 30 | * @param type The type of the event. Possible values are: FaceEvent.UPDATED. 31 | * @param clip A reference to the clipping object that is relevant to the event. 32 | */ 33 | public function ClippingEvent(type:String, clipping:Clipping) 34 | { 35 | super(type); 36 | this.clipping = clipping; 37 | } 38 | 39 | /** 40 | * Creates a copy of the FaceEvent object and sets the value of each property to match that of the original. 41 | */ 42 | public override function clone():Event 43 | { 44 | return new ClippingEvent(type, clipping); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/away3dlite/materials/WireframeMaterial.as: -------------------------------------------------------------------------------- 1 | package away3dlite.materials 2 | { 3 | import flash.display.*; 4 | 5 | /** 6 | * Outline material. 7 | */ 8 | public class WireframeMaterial extends Material 9 | { 10 | private var _color:uint; 11 | private var _alpha:Number; 12 | 13 | /** 14 | * Defines the color of the outline. 15 | */ 16 | public function get color():uint 17 | { 18 | return _color; 19 | } 20 | 21 | public function set color(val:uint):void 22 | { 23 | if (_color == val) 24 | return; 25 | 26 | _color = val; 27 | 28 | (_graphicsStroke.fill as GraphicsSolidFill).color = _color; 29 | } 30 | 31 | /** 32 | * Defines the transparency of the outline. 33 | */ 34 | public function get alpha():Number 35 | { 36 | return _alpha; 37 | } 38 | 39 | public function set alpha(val:Number):void 40 | { 41 | if (_alpha == val) 42 | return; 43 | 44 | _alpha = val; 45 | 46 | (_graphicsStroke.fill as GraphicsSolidFill).alpha = _alpha; 47 | } 48 | 49 | /** 50 | * Creates a new WireframeMaterial object. 51 | * 52 | * @param color The color of the outline. 53 | * @param alpha The transparency of the outline. 54 | */ 55 | public function WireframeMaterial(color:int = 0xFFFFFF, alpha:Number = 1) 56 | { 57 | super(); 58 | 59 | _color = color; 60 | _alpha = alpha; 61 | 62 | _graphicsStroke.fill = new GraphicsSolidFill(_color, _alpha); 63 | _graphicsStroke.thickness = 1; 64 | 65 | graphicsData = Vector.([_graphicsStroke, _triangles]); 66 | graphicsData.fixed = true; 67 | 68 | trianglesIndex = 1; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /pbk/normalMapping.pbk: -------------------------------------------------------------------------------- 1 | 2 | 3 | kernel normalMapping 4 | < namespace : "AIF"; 5 | vendor : "Adobe Systems, Inc."; 6 | version : 2; 7 | description : "normalMapping"; > 8 | { 9 | 10 | parameter float4 diffuseMatrixR; 11 | parameter float4 diffuseMatrixG; 12 | parameter float4 diffuseMatrixB; 13 | parameter float4 diffuseMatrixO; 14 | parameter float4 ambientMatrixO; 15 | 16 | parameter float4 specularMatrixR; 17 | parameter float4 specularMatrixG; 18 | parameter float4 specularMatrixB; 19 | parameter float4 specularMatrixO; 20 | 21 | input image4 lightMap; 22 | 23 | input image4 normalMap; 24 | 25 | 26 | output pixel4 dst; 27 | 28 | // evaluatePixel(): The function of the filter that actually does the 29 | // processing of the image. This function is called once 30 | // for each pixel of the output image. 31 | void 32 | evaluatePixel() 33 | { 34 | // Obtain the texture pixel color 35 | float4 textureColor = sampleNearest(lightMap, outCoord()); 36 | 37 | // Obtain the normalmap pixel color 38 | float4 mapColor = sampleNearest(normalMap, outCoord()); 39 | 40 | // set the output 41 | float4 diffuse = (max(mapColor.r*diffuseMatrixR + mapColor.g*diffuseMatrixG + mapColor.b*diffuseMatrixB + diffuseMatrixO, float4(0.0, 0.0, 0.0, 0.0)) + ambientMatrixO); 42 | float4 specular = mapColor.r*specularMatrixR + mapColor.g*specularMatrixG + mapColor.b*specularMatrixB + specularMatrixO; 43 | dst = sampleNearest(lightMap, outCoord()) + diffuse + clamp(specular, float4(0.0, 0.0, 0.0, 0.0), float4(1.0, 1.0, 1.0, 1.0)); 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/away3dlite/core/utils/Debug.as: -------------------------------------------------------------------------------- 1 | package away3dlite.core.utils 2 | { 3 | /** 4 | * Class for emmiting debuging messages, warnings and errors. 5 | */ 6 | public class Debug 7 | { 8 | /** 9 | * Determines whether debug mode is active. Defaults to false. 10 | */ 11 | public static var active:Boolean = false; 12 | 13 | /** 14 | * Determines whether warning messages are treated as errors. Defaults to false. 15 | */ 16 | public static var warningsAsErrors:Boolean = false; 17 | 18 | /** 19 | * Traces a message to the output window. 20 | * 21 | * @param message The message to trace. 22 | */ 23 | public static function trace(...agrs):void 24 | { 25 | if (active) 26 | doTrace(agrs); 27 | } 28 | 29 | /** 30 | * Traces a warning message to the output window. If the warningsAsErrors property is set to true, a runtime error is thrown. 31 | * 32 | * @see #warningsAsErrors 33 | * 34 | * @param message The warning message to trace. 35 | */ 36 | public static function warning(message:Object):void 37 | { 38 | if (warningsAsErrors) 39 | { 40 | error(message); 41 | return; 42 | } 43 | trace("WARNING: "+message); 44 | } 45 | 46 | /** 47 | * Traces an error message to the output window and throws a runtime error. 48 | * 49 | * @param message The error message to trace. 50 | */ 51 | public static function error(message:Object):void 52 | { 53 | trace("ERROR: "+message); 54 | throw new Error(message); 55 | } 56 | } 57 | } 58 | 59 | /** 60 | * @private 61 | */ 62 | function doTrace(...agrs):void 63 | { 64 | trace.apply(this, agrs); 65 | } -------------------------------------------------------------------------------- /src/away3dlite/events/ParserEvent.as: -------------------------------------------------------------------------------- 1 | package away3dlite.events { import away3dlite.core.base.*; import away3dlite.loaders.*; import flash.events.*; /** * Passed as a parameter when a 3d object loader event occurs */ public class ParserEvent extends Event { /** * Defines the value of the type property of a parseSuccess event object. */ public static const PARSE_SUCCESS:String = "parseSuccess"; /** * Defines the value of the type property of a parseError event object. */ public static const PARSE_ERROR:String = "parseError"; /** * Defines the value of the type property of a parseProgress event object. */ public static const PARSE_PROGRESS:String = "parseProgress"; /** * A reference to the loader object that is relevant to the event. */ public var parser:AbstractParser; /** * A reference to the parsed object that is relevant to the event. */ public var result:Object3D; /** * Creates a new ParserEvent object. * * @param type The type of the event. Possible values are: Loader3DEvent.PARSE_SUCCESS, Loader3DEvent.PARSE_ERROR and Loader3DEvent.PARSE_PROGRESS. * @param parser A reference to the parser object that is relevant to the event. * @param result A reference to the parsed object that is relevant to the event. */ public function ParserEvent(type:String, parser:AbstractParser, result:Object3D) { super(type); this.parser = parser; this.result = result; } /** * Creates a copy of the Loader3DEvent object and sets the value of each property to match that of the original. */ public override function clone():Event { return new ParserEvent(type, parser, result); } } } -------------------------------------------------------------------------------- /src/away3dlite/loaders/utils/GeometryLibrary.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.utils { import away3dlite.core.utils.Debug; import away3dlite.loaders.data.*; import flash.utils.Dictionary; /** * Store for all geometries associated with an externally loaded file. */ public dynamic class GeometryLibrary extends Dictionary { private var _geometryArray:Array; private var _geometryArrayDirty:Boolean; private function updateGeometryArray():void { _geometryArray = []; for each (var _geometry:GeometryData in this) { _geometryArray.push(_geometry); } } /** * The name of the geometry used as a unique reference. */ public var name:String; /** * Adds a geometry name reference to the library. */ public function addGeometry(name:String, geoXML:XML = null, ctrlXML:XML = null):GeometryData { //return if geometry already exists if (this[name]) return this[name]; _geometryArrayDirty = true; var geometryData:GeometryData = new GeometryData(); geometryData.geoXML = geoXML; geometryData.ctrlXML = ctrlXML; this[geometryData.name = name] = geometryData; return geometryData; } /** * Returns a geometry data object for the given name reference in the library. */ public function getGeometry(name:String):GeometryData { //return if geometry exists if (this[name]) return this[name]; Debug.warning("Geometry '" + name + "' does not exist"); return null; } /** * Returns an array of all geometries. */ public function getGeometryArray():Array { if (_geometryArrayDirty) updateGeometryArray(); return _geometryArray; } } } -------------------------------------------------------------------------------- /src/away3dlite/primitives/AbstractPrimitive.as: -------------------------------------------------------------------------------- 1 | package away3dlite.primitives 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.base.*; 5 | import away3dlite.materials.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * Abstract base class for shaded primitives 11 | */ 12 | public class AbstractPrimitive extends Mesh 13 | { 14 | /** @private */ 15 | arcane var _primitiveDirty:Boolean; 16 | 17 | protected function updatePrimitive():void 18 | { 19 | buildPrimitive(); 20 | 21 | buildFaces(); 22 | } 23 | 24 | /** 25 | * Builds the vertex, face and uv objects that make up the 3d primitive. 26 | */ 27 | protected function buildPrimitive():void 28 | { 29 | _primitiveDirty = false; 30 | 31 | _vertices.fixed = false; 32 | _uvtData.fixed = false; 33 | _indices.fixed = false; 34 | _faceLengths.fixed = false; 35 | 36 | _vertices.length = 0; 37 | _uvtData.length = 0; 38 | _indices.length = 0; 39 | _faceLengths.length = 0; 40 | } 41 | 42 | /** 43 | * @inheritDoc 44 | */ 45 | public override function get vertices():Vector. 46 | { 47 | if (_primitiveDirty) 48 | updatePrimitive(); 49 | 50 | return _vertices; 51 | } 52 | 53 | /** 54 | * @inheritDoc 55 | */ 56 | public override function get faces():Vector. 57 | { 58 | if (_primitiveDirty) 59 | updatePrimitive(); 60 | 61 | return super.faces; 62 | } 63 | 64 | /** 65 | * Creates a new AbstractPrimitive object. 66 | * 67 | * @param material Defines the global material used on the faces in the primitive. 68 | */ 69 | public function AbstractPrimitive(material:Material = null) 70 | { 71 | super(material); 72 | 73 | _primitiveDirty = true; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /src/away3dlite/animators/bones/SkinVertex.as: -------------------------------------------------------------------------------- 1 | package away3dlite.animators.bones 2 | { 3 | import flash.geom.*; 4 | 5 | public class SkinVertex 6 | { 7 | private var _i:int; 8 | private var _position:Vector3D = new Vector3D(); 9 | private var _output:Vector3D; 10 | private var _startIndex:int; 11 | private var _vertices:Vector.; 12 | private var _baseVertex:Vector3D; 13 | 14 | public var weights:Vector. = new Vector.(); 15 | 16 | public var controllers:Vector. = new Vector.(); 17 | 18 | public function SkinVertex() 19 | { 20 | } 21 | 22 | public function updateVertices(startIndex:int, vertices:Vector.):void 23 | { 24 | _startIndex = startIndex; 25 | _vertices = vertices; 26 | _baseVertex = new Vector3D(_vertices[_startIndex], _vertices[_startIndex + 1], _vertices[_startIndex + 2]); 27 | } 28 | 29 | public function update():void 30 | { 31 | //reset values 32 | _output = new Vector3D(); 33 | 34 | _i = weights.length; 35 | while (_i--) { 36 | _position = controllers[_i].transformMatrix3D.transformVector(_baseVertex); 37 | _position.scaleBy(weights[_i]); 38 | _output = _output.add(_position); 39 | } 40 | 41 | _vertices[int(_startIndex)] = _output.x; 42 | _vertices[int(_startIndex + 1)] = _output.y; 43 | _vertices[int(_startIndex + 2)] = _output.z; 44 | } 45 | 46 | public function clone():SkinVertex 47 | { 48 | var skinVertex:SkinVertex = new SkinVertex(); 49 | skinVertex.weights = weights; 50 | skinVertex.controllers = controllers; 51 | 52 | return skinVertex; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/away3dlite/materials/ColorMaterial.as: -------------------------------------------------------------------------------- 1 | package away3dlite.materials 2 | { 3 | import away3dlite.core.utils.*; 4 | 5 | import flash.display.*; 6 | 7 | /** 8 | * Basic color material. 9 | */ 10 | public class ColorMaterial extends Material 11 | { 12 | private var _color:uint; 13 | private var _alpha:Number; 14 | 15 | /** 16 | * Defines the color of the material. Default value is random. 17 | */ 18 | public function get color():uint 19 | { 20 | return _color; 21 | } 22 | 23 | public function set color(val:uint):void 24 | { 25 | if (_color == val) 26 | return; 27 | 28 | _color = val; 29 | 30 | _graphicsBitmapFill.bitmapData = new BitmapData(2, 2, _alpha < 1, int(_alpha * 0xFF) << 24 | _color); 31 | } 32 | 33 | /** 34 | * Defines the transparency of the material. Default value is 1. 35 | */ 36 | public function get alpha():Number 37 | { 38 | return _alpha; 39 | } 40 | 41 | public function set alpha(val:Number):void 42 | { 43 | if (_alpha == val) 44 | return; 45 | 46 | _alpha = val; 47 | 48 | _graphicsBitmapFill.bitmapData = new BitmapData(2, 2, _alpha < 1, int(_alpha * 0xFF) << 24 | _color); 49 | } 50 | 51 | /** 52 | * Creates a new BitmapMaterial object. 53 | * 54 | * @param color The color of the material. 55 | * @param alpha The transparency of the material. 56 | */ 57 | public function ColorMaterial(color:* = null, alpha:Number = 1) 58 | { 59 | super(); 60 | 61 | _color = Cast.color((color == null) ? "random" : color); 62 | _alpha = alpha; 63 | 64 | _graphicsBitmapFill = new GraphicsBitmapFill(new BitmapData(2, 2, _alpha < 1, int(_alpha * 0xFF) << 24 | _color)); 65 | 66 | graphicsData = Vector.([_graphicsStroke, _graphicsBitmapFill, _triangles, _graphicsEndFill]); 67 | graphicsData.fixed = true; 68 | 69 | trianglesIndex = 2; 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /src/away3dlite/loaders/utils/ChannelLibrary.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.utils 2 | { 3 | import away3dlite.core.utils.Debug; 4 | import away3dlite.loaders.data.*; 5 | 6 | import flash.utils.Dictionary; 7 | 8 | /** 9 | * Store for all animation channels associated with an externally loaded file. 10 | */ 11 | public dynamic class ChannelLibrary extends Dictionary 12 | { 13 | private var _channelArray:Array; 14 | private var _channelArrayDirty:Boolean; 15 | 16 | private function updateChannelArray():void 17 | { 18 | _channelArray = []; 19 | for each (var _channel:ChannelData in this) { 20 | _channelArray.push(_channel); 21 | } 22 | } 23 | 24 | /** 25 | * Adds an animation channel name reference to the library. 26 | */ 27 | public function addChannel(name:String, xml:XML, channelIndex:int):ChannelData 28 | { 29 | //return if animation already exists 30 | if (this[name]) 31 | return this[name]; 32 | 33 | _channelArrayDirty = true; 34 | 35 | var channelData:ChannelData = new ChannelData(); 36 | channelData.xml = xml; 37 | channelData.channelIndex = channelIndex; 38 | this[channelData.name = name] = channelData; 39 | return channelData; 40 | } 41 | 42 | /** 43 | * Returns an animation channel data object for the given name reference in the library. 44 | */ 45 | public function getChannel(name:String):ChannelData 46 | { 47 | //return if animation exists 48 | if (this[name]) 49 | return this[name]; 50 | 51 | Debug.warning("Channel '" + name + "' does not exist"); 52 | 53 | return null; 54 | } 55 | 56 | /** 57 | * Returns an array of all animation channels. 58 | */ 59 | public function getChannelArray():Array 60 | { 61 | if (_channelArrayDirty) 62 | updateChannelArray(); 63 | 64 | return _channelArray; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/AnimationData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { 3 | import away3dlite.animators.*; 4 | import away3dlite.containers.*; 5 | import away3dlite.core.base.*; 6 | 7 | import flash.utils.*; 8 | 9 | /** 10 | * Data class for the animation of a mesh. 11 | * 12 | * @see away3dlite.loaders.data.MeshData 13 | */ 14 | public class AnimationData 15 | { 16 | /** 17 | * String representing a vertex animation. 18 | */ 19 | public static const VERTEX_ANIMATION:String = "vertexAnimation"; 20 | 21 | /** 22 | * String representing a skin animation. 23 | */ 24 | public static const SKIN_ANIMATION:String = "skinAnimation"; 25 | 26 | /** 27 | * The name of the animation used as a unique reference. 28 | */ 29 | public var name:String; 30 | 31 | /** 32 | * Reference to the animation object of the resulting animation. 33 | */ 34 | public var animation:BonesAnimator; 35 | 36 | /** 37 | * Reference to the time the animation starts. 38 | */ 39 | public var start:Number = Infinity; 40 | 41 | /** 42 | * Reference to the number of seconds the animation ends. 43 | */ 44 | public var end:Number = 0; 45 | 46 | /** 47 | * String representing the animation type. 48 | */ 49 | public var animationType:String = SKIN_ANIMATION; 50 | 51 | /** 52 | * Dictonary of names representing the animation channels used in the animation. 53 | */ 54 | public var channels:Dictionary = new Dictionary(true); 55 | 56 | /** 57 | * Duplicates the animation data's properties to another AnimationData object 58 | * 59 | * @param object The new object instance into which all properties are copied 60 | * @return The new object instance with duplicated properties applied 61 | */ 62 | public function clone(object:Object3D):AnimationData 63 | { 64 | var animationData:AnimationData = object.animationLibrary.addAnimation(name); 65 | 66 | animationData.start = start; 67 | animationData.end = end; 68 | animationData.animationType = animationType; 69 | animationData.animation = animation.clone(object as ObjectContainer3D); 70 | 71 | return animationData; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /src/away3dlite/lights/PointLight3D.as: -------------------------------------------------------------------------------- 1 | package away3dlite.lights 2 | { 3 | 4 | /** 5 | * @author robbateman 6 | */ 7 | public class PointLight3D extends AbstractLight3D 8 | { 9 | 10 | private var _ambient:Number; 11 | private var _diffuse:Number; 12 | private var _specular:Number; 13 | 14 | private var _x:Number; 15 | private var _y:Number; 16 | private var _z:Number; 17 | 18 | 19 | /** 20 | * 21 | */ 22 | public function get ambient():Number 23 | { 24 | return _ambient; 25 | } 26 | 27 | public function set ambient(val:Number):void 28 | { 29 | if (_ambient == val) 30 | return; 31 | 32 | _ambient = val; 33 | } 34 | 35 | /** 36 | * 37 | */ 38 | public function get diffuse():Number 39 | { 40 | return _diffuse; 41 | } 42 | 43 | public function set diffuse(val:Number):void 44 | { 45 | if (_diffuse == val) 46 | return; 47 | 48 | _diffuse = val; 49 | } 50 | 51 | /** 52 | * 53 | */ 54 | public function get specular():Number 55 | { 56 | return _specular; 57 | } 58 | 59 | public function set specular(val:Number):void 60 | { 61 | if (_specular == val) 62 | return; 63 | 64 | _specular = val; 65 | } 66 | 67 | /** 68 | * 69 | */ 70 | public function get x():Number 71 | { 72 | return _x; 73 | } 74 | 75 | public function set x(val:Number):void 76 | { 77 | if (_x == val) 78 | return; 79 | 80 | _x = val; 81 | } 82 | 83 | /** 84 | * 85 | */ 86 | public function get y():Number 87 | { 88 | return _y; 89 | } 90 | 91 | public function set y(val:Number):void 92 | { 93 | if (_y == val) 94 | return; 95 | 96 | _y = val; 97 | } 98 | 99 | /** 100 | * 101 | */ 102 | public function get z():Number 103 | { 104 | return _z; 105 | } 106 | 107 | public function set z(val:Number):void 108 | { 109 | if (_z == val) 110 | return; 111 | 112 | _z = val; 113 | } 114 | 115 | 116 | /** 117 | * 118 | */ 119 | public function PointLight3D() 120 | { 121 | 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/away3dlite/primitives/LineSegment.as: -------------------------------------------------------------------------------- 1 | package away3dlite.primitives 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.materials.*; 5 | 6 | import flash.geom.*; 7 | 8 | use namespace arcane; 9 | 10 | /** 11 | * Creates a single 3d line segment. 12 | */ 13 | public class LineSegment extends AbstractPrimitive 14 | { 15 | private var _start:Vector3D; 16 | private var _end:Vector3D; 17 | 18 | /** 19 | * @inheritDoc 20 | */ 21 | protected override function buildPrimitive():void 22 | { 23 | super.buildPrimitive(); 24 | 25 | _vertices.push(_start.x, _start.y, _start.z); 26 | _uvtData.push(0, 0, 0); 27 | 28 | _vertices.push(_end.x, _end.y, _end.z); 29 | _uvtData.push(0, 0, 0); 30 | 31 | _indices.push(0, 1, 1); 32 | _faceLengths.push(3); 33 | } 34 | 35 | /** 36 | * Defines the starting position of the line segment. Defaults to (0, 0, 0). 37 | */ 38 | public function set start(value:Vector3D):void 39 | { 40 | _start.x = value.x; 41 | _start.y = value.y; 42 | _start.z = value.z; 43 | 44 | _primitiveDirty = true; 45 | } 46 | 47 | public function get start():Vector3D 48 | { 49 | return _start; 50 | } 51 | 52 | /** 53 | * Defines the ending position of the line segment. Defaults to (100, 100, 100). 54 | */ 55 | public function set end(value:Vector3D):void 56 | { 57 | _end.x = value.x; 58 | _end.y = value.y; 59 | _end.z = value.z; 60 | 61 | _primitiveDirty = true; 62 | } 63 | 64 | public function get end():Vector3D 65 | { 66 | return _end; 67 | } 68 | 69 | /** 70 | * Creates a new LineSegment object. 71 | * 72 | * @param material Defines the global material used on the faces in the plane. 73 | * @param start Defines the starting position of the line segment. 74 | * @param end Defines the ending position of the line segment. 75 | */ 76 | public function LineSegment(material:Material = null, start:Vector3D = null, end:Vector3D = null) 77 | { 78 | super(material); 79 | 80 | _start = start || new Vector3D(0, 0, 0); 81 | _end = end || new Vector3D(100, 100, 100); 82 | 83 | this.bothsides = true; 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /src/away3dlite/materials/BitmapMaterial.as: -------------------------------------------------------------------------------- 1 | package away3dlite.materials 2 | { 3 | import flash.display.*; 4 | 5 | /** 6 | * Basic bitmap material 7 | */ 8 | public class BitmapMaterial extends Material 9 | { 10 | /** 11 | * Defines the bitmapData object to be used as the material's texture. 12 | */ 13 | public function get bitmap():BitmapData 14 | { 15 | return _graphicsBitmapFill.bitmapData; 16 | } 17 | 18 | public function set bitmap(val:BitmapData):void 19 | { 20 | _graphicsBitmapFill.bitmapData = val; 21 | } 22 | 23 | /** 24 | * Defines whether repeat is used when drawing the material. 25 | */ 26 | public function get repeat():Boolean 27 | { 28 | return _graphicsBitmapFill.repeat; 29 | } 30 | 31 | public function set repeat(val:Boolean):void 32 | { 33 | _graphicsBitmapFill.repeat = val; 34 | } 35 | 36 | /** 37 | * Defines whether smoothing is used when drawing the material. 38 | */ 39 | public function get smooth():Boolean 40 | { 41 | return _graphicsBitmapFill.smooth; 42 | } 43 | 44 | public function set smooth(val:Boolean):void 45 | { 46 | _graphicsBitmapFill.smooth = val; 47 | } 48 | 49 | /** 50 | * Returns the width of the material's bitmapdata object. 51 | */ 52 | public function get width():int 53 | { 54 | return _graphicsBitmapFill.bitmapData.width; 55 | } 56 | 57 | /** 58 | * Returns the height of the material's bitmapdata object. 59 | */ 60 | public function get height():int 61 | { 62 | return _graphicsBitmapFill.bitmapData.height; 63 | } 64 | 65 | /** 66 | * Creates a new BitmapMaterial object. 67 | * 68 | * @param bitmap The bitmapData object to be used as the material's texture. 69 | */ 70 | public function BitmapMaterial(bitmap:BitmapData = null) 71 | { 72 | super(); 73 | 74 | _graphicsBitmapFill.bitmapData = bitmap || new BitmapData(100, 100, false, 0x000000); 75 | 76 | graphicsData = Vector.([_graphicsStroke, _graphicsBitmapFill, _triangles, _graphicsEndFill]); 77 | graphicsData.fixed = true; 78 | 79 | trianglesIndex = 2; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/away3dlite/animators/bones/SkinController.as: -------------------------------------------------------------------------------- 1 | package away3dlite.animators.bones 2 | { 3 | import away3dlite.containers.*; 4 | 5 | import flash.display.*; 6 | import flash.geom.*; 7 | 8 | /** 9 | * Stores the connection between a Bone and a collection of SkinVertices in a bones animation. 10 | * 11 | * @see away3dlite.animators.BonesAnimator 12 | */ 13 | public class SkinController 14 | { 15 | private var _transformMatrix3D:Matrix3D; 16 | 17 | /** 18 | * Reference to the name of the controlling Bone object. 19 | */ 20 | public var name:String; 21 | 22 | /** 23 | * Reference to the joint of the controlling Bone object. 24 | */ 25 | public var joint:ObjectContainer3D; 26 | 27 | /** 28 | * Defines the 3d matrix that transforms the position of the Bone to the position of the SkinVertices. 29 | */ 30 | public var bindMatrix:Matrix3D; 31 | 32 | /** 33 | * Defines the containing 3d object that holds the Mesh to which the SkinVertex objects belong. 34 | */ 35 | public var parent:ObjectContainer3D; 36 | 37 | /** 38 | * Store of all SkinVertex being controlled 39 | */ 40 | public var skinVertices:Vector. = new Vector.(); 41 | 42 | /** 43 | * Returns the 3d transform matrix to apply to the SkinVertex objects. 44 | */ 45 | public function get transformMatrix3D():Matrix3D 46 | { 47 | return _transformMatrix3D; 48 | } 49 | 50 | /** 51 | * Updates the 3d transform matrix. 52 | */ 53 | public function update():void 54 | { 55 | if (!joint) 56 | return; 57 | 58 | _transformMatrix3D = joint.transform.matrix3D.clone(); 59 | var child:DisplayObjectContainer = joint; 60 | 61 | while (child.parent != parent) { 62 | child = child.parent; 63 | _transformMatrix3D.append(child.transform.matrix3D); 64 | } 65 | _transformMatrix3D.prepend(bindMatrix); 66 | } 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/away3dlite/materials/WireColorMaterial.as: -------------------------------------------------------------------------------- 1 | package away3dlite.materials 2 | { 3 | import away3dlite.core.utils.*; 4 | 5 | import flash.display.*; 6 | 7 | /** 8 | * Color material with an outline. 9 | */ 10 | public class WireColorMaterial extends ColorMaterial 11 | { 12 | private var _wireColor:uint; 13 | private var _wireAlpha:Number; 14 | private var _thickness:Number; 15 | 16 | /** 17 | * Defines the color of the outline. 18 | */ 19 | public function get wireColor():uint 20 | { 21 | return _wireColor; 22 | } 23 | public function set wireColor(val:uint):void 24 | { 25 | if (_wireColor == val) 26 | return; 27 | 28 | _wireColor = val; 29 | 30 | (_graphicsStroke.fill as GraphicsSolidFill).color = _wireColor; 31 | } 32 | 33 | /** 34 | * Defines the transparency of the outline. 35 | */ 36 | public function get wireAlpha():Number 37 | { 38 | return _wireAlpha; 39 | } 40 | 41 | public function set wireAlpha(val:Number):void 42 | { 43 | if (_wireAlpha == val) 44 | return; 45 | 46 | _wireAlpha = val; 47 | 48 | (_graphicsStroke.fill as GraphicsSolidFill).alpha = _wireAlpha; 49 | } 50 | 51 | /** 52 | * Defines the thickness of the outline. 53 | */ 54 | public function get thickness():Number 55 | { 56 | return _thickness; 57 | } 58 | public function set thickness(val:Number):void 59 | { 60 | if (_thickness == val) 61 | return; 62 | 63 | _thickness = val; 64 | 65 | _graphicsStroke.thickness = _thickness; 66 | } 67 | 68 | /** 69 | * Creates a new WireColorMaterial object. 70 | * 71 | * @param color The color of the material. 72 | * @param alpha The transparency of the material. 73 | * @param wireColor The color of the outline. 74 | * @param wireAlpha The transparency of the outline. 75 | * @param thickness The thickness of the outline. 76 | */ 77 | public function WireColorMaterial(color:* = null, alpha:Number = 1, wireColor:* = null, wireAlpha:Number = 1, thickness:Number = 1) 78 | { 79 | super(color, alpha); 80 | 81 | _wireColor = Cast.color(wireColor || 0x000000); 82 | _wireAlpha = wireAlpha; 83 | 84 | _thickness = thickness; 85 | 86 | _graphicsStroke.fill = new GraphicsSolidFill(_wireColor, _wireAlpha); 87 | _graphicsStroke.thickness = _thickness; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/away3dlite/loaders/utils/MaterialLibrary.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.utils { import away3dlite.core.utils.Debug; import away3dlite.loaders.data.*; import away3dlite.materials.*; import flash.display.BitmapData; import flash.utils.Dictionary; /** * Store for all materials associated with an externally loaded file. */ public dynamic class MaterialLibrary extends Dictionary { private var length:int = 0; /** * The root directory path to the texture files. */ public var texturePath:String; /** * Flag to determine if any of the contained textures require a file load. */ public var loadRequired:Boolean; /** * Adds a material name reference to the library. */ public function addMaterial(name:String):MaterialData { //return if material already exists if (this[name]) return this[name]; length++; var materialData:MaterialData = new MaterialData(); this[materialData.name = name] = materialData; return materialData; } /** * Returns a material data object for the given name reference in the library. */ public function getMaterial(name:String):MaterialData { //return if material exists if (this[name]) return this[name]; Debug.warning("Material '" + name + "' does not exist"); return null; } /** * Called after all textures have been loaded from the TextureLoadQueue class. * * @see away3dlite.loaders.Loader3D * @see away3dlite.loaders.utils.TextureLoadQueue */ public function texturesLoaded(loadQueue:TextureLoadQueue):void { loadRequired = false; var images:Array = loadQueue.images; var _materialData:MaterialData; var _image:TextureLoader; for each (_materialData in this) { for each (_image in images) { if (texturePath + _materialData.textureFileName == _image.filename) { try{ _materialData.textureBitmap = new BitmapData(_image.width, _image.height, true, 0x00FFFFFF); _materialData.textureBitmap.draw(_image); _materialData.material = new BitmapMaterial(_materialData.textureBitmap); }catch(e:*){ Debug.warning("File not found : " + texturePath + _materialData.textureFileName ); _materialData.material = new WireframeMaterial(); } } } } } } } -------------------------------------------------------------------------------- /src/away3dlite/events/MaterialEvent.as: -------------------------------------------------------------------------------- 1 | package away3dlite.events 2 | { 3 | import away3dlite.materials.*; 4 | 5 | import flash.events.*; 6 | 7 | /** 8 | * Passed as a parameter when a material event occurs 9 | */ 10 | public class MaterialEvent extends Event 11 | { 12 | /** 13 | * Defines the value of the type property of a loadError event object. 14 | */ 15 | public static const LOAD_ERROR:String = "loadError"; 16 | 17 | /** 18 | * Defines the value of the type property of a loadProgress event object. 19 | */ 20 | public static const LOAD_PROGRESS:String = "loadProgress"; 21 | 22 | /** 23 | * Defines the value of the type property of a loadSuccess event object. 24 | */ 25 | public static const LOAD_SUCCESS:String = "loadSuccess"; 26 | 27 | /** 28 | * Defines the value of the type property of a materialUpdated event object. 29 | */ 30 | public static const MATERIAL_UPDATED:String = "materialUpdated"; 31 | 32 | /** 33 | * Defines the value of the type property of a materialChanged event object. 34 | */ 35 | public static const MATERIAL_CHANGED:String = "materialChanged"; 36 | 37 | /** 38 | * Defines the value of the type property of a materialActivated event object. 39 | */ 40 | public static const MATERIAL_ACTIVATED:String = "materialActivated"; 41 | 42 | /** 43 | * Defines the value of the type property of a materialDeactivated event object. 44 | */ 45 | public static const MATERIAL_DEACTIVATED:String = "materialDeactivated"; 46 | 47 | /** 48 | * A reference to the material object that is relevant to the event. 49 | */ 50 | public var material:Material; 51 | 52 | /** 53 | * A reference to a user defined extra object that is relevant to the event. 54 | */ 55 | public var extra:Object; 56 | 57 | /** 58 | * Creates a new MaterialEvent object. 59 | * 60 | * @param type The type of the event. Possible values are: MaterialEvent.RESIZED. 61 | * @param material A reference to the material object that is relevant to the event. 62 | */ 63 | public function MaterialEvent(type:String, material:Material) 64 | { 65 | super(type); 66 | this.material = material; 67 | } 68 | 69 | /** 70 | * Creates a copy of the MaterialEvent object and sets the value of each property to match that of the original. 71 | */ 72 | public override function clone():Event 73 | { 74 | return new MaterialEvent(type, material); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/GeometryData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { import away3dlite.animators.bones.SkinVertex; 3 | 4 | /** 5 | * Data class for the geometry data used in a mesh object 6 | */ 7 | public class GeometryData 8 | { 9 | /** 10 | * The name of the geometry used as a unique reference. 11 | */ 12 | public var name:String; 13 | 14 | /** 15 | * Array of vertex data. 16 | */ 17 | public var vertices:Vector. = new Vector.(); 18 | 19 | /** 20 | * Array of skinvertex data. 21 | */ 22 | public var skinVertices:Vector. = new Vector.(); 23 | 24 | /** 25 | * Array of uv data. 26 | */ 27 | public var uvtData:Vector. = new Vector.(); 28 | 29 | /** 30 | * Array of indices data. 31 | */ 32 | public var indices:Vector. = new Vector.(); 33 | 34 | /** 35 | * Array of face indices length data. 36 | */ 37 | public var faceLengths:Vector. = new Vector.(); 38 | 39 | /** 40 | * Array of face data objects. 41 | * 42 | * @see away3dlite.loaders.data.FaceData 43 | */ 44 | public var faces:Array = []; 45 | 46 | /** 47 | * Optional assigned materials to the geometry. 48 | */ 49 | public var materials:Array = []; 50 | 51 | /** 52 | * Defines whether both sides of the geometry are visible 53 | */ 54 | public var bothsides:Boolean; 55 | 56 | /** 57 | * Array of skin controller objects used in bone animations 58 | * 59 | * @see away3dlite.animators.skin.SkinController 60 | */ 61 | public var skinControllers:Array = []; 62 | 63 | /** 64 | * Reference to the xml object defining the geometry. 65 | */ 66 | public var geoXML:XML; 67 | 68 | /** 69 | * Reference to the xml object defining the controller. 70 | */ 71 | public var ctrlXML:XML; 72 | 73 | /** 74 | * Returns the maximum x value of the geometry data 75 | */ 76 | public var maxX:Number; 77 | 78 | /** 79 | * Returns the minimum x value of the geometry data 80 | */ 81 | public var minX:Number; 82 | 83 | /** 84 | * Returns the maximum y value of the geometry data 85 | */ 86 | public var maxY:Number; 87 | 88 | /** 89 | * Returns the minimum y value of the geometry data 90 | */ 91 | public var minY:Number; 92 | 93 | /** 94 | * Returns the maximum z value of the geometry data 95 | */ 96 | public var maxZ:Number; 97 | 98 | /** 99 | * Returns the minimum z value of the geometry data 100 | */ 101 | public var minZ:Number; 102 | } 103 | } -------------------------------------------------------------------------------- /src/away3dlite/materials/BitmapFileMaterial.as: -------------------------------------------------------------------------------- 1 | package away3dlite.materials 2 | { 3 | import away3dlite.events.*; 4 | 5 | import flash.display.*; 6 | import flash.events.*; 7 | import flash.net.*; 8 | 9 | /** 10 | * Dispatched when the material completes a file load successfully. 11 | * 12 | * @eventType away3dlite.events.MaterialEvent 13 | */ 14 | [Event(name="loadSuccess",type="away3dlite.events.MaterialEvent")] 15 | 16 | /** 17 | * Dispatched when the material fails to load a file. 18 | * 19 | * @eventType away3dlite.events.MaterialEvent 20 | */ 21 | [Event(name="loadError",type="away3dlite.events.MaterialEvent")] 22 | 23 | /** 24 | * Dispatched every frame the material is loading. 25 | * 26 | * @eventType away3dlite.events.MaterialEvent 27 | */ 28 | [Event(name="loadProgress",type="away3dlite.events.MaterialEvent")] 29 | 30 | /** 31 | * Bitmap material that loads it's texture from an external bitmapasset file. 32 | */ 33 | public class BitmapFileMaterial extends BitmapMaterial 34 | { 35 | private var _loader:Loader; 36 | private var _materialloaderror:MaterialEvent; 37 | private var _materialloadprogress:MaterialEvent; 38 | private var _materialloadsuccess:MaterialEvent; 39 | 40 | private function onError(e:IOErrorEvent):void 41 | { 42 | if (!_materialloaderror) 43 | _materialloaderror = new MaterialEvent(MaterialEvent.LOAD_ERROR, this); 44 | 45 | dispatchEvent(_materialloaderror); 46 | } 47 | 48 | private function onProgress(e:ProgressEvent):void 49 | { 50 | if (!_materialloadprogress) 51 | _materialloadprogress = new MaterialEvent(MaterialEvent.LOAD_PROGRESS, this); 52 | 53 | dispatchEvent(_materialloadprogress); 54 | } 55 | 56 | private function onComplete(e:Event):void 57 | { 58 | bitmap = Bitmap(_loader.content).bitmapData; 59 | 60 | if (!_materialloadsuccess) 61 | _materialloadsuccess = new MaterialEvent(MaterialEvent.LOAD_SUCCESS, this); 62 | 63 | dispatchEvent(_materialloadsuccess); 64 | } 65 | 66 | /** 67 | * Creates a new BitmapFileMaterial object. 68 | * 69 | * @param url The location of the bitmapasset to load. 70 | */ 71 | public function BitmapFileMaterial(url:String="") 72 | { 73 | super(new BitmapData(100,100)); 74 | 75 | _loader = new Loader(); 76 | _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError); 77 | _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress); 78 | _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete); 79 | _loader.load(new URLRequest(url)); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/away3dlite/primitives/Trident.as: -------------------------------------------------------------------------------- 1 | package away3dlite.primitives 2 | { 3 | import away3dlite.containers.ObjectContainer3D; 4 | import away3dlite.materials.WireframeMaterial; 5 | 6 | import flash.geom.Vector3D; 7 | 8 | /** 9 | * Creates an axis trident. 10 | */ 11 | public class Trident extends ObjectContainer3D 12 | { 13 | private var _lines:Vector.; 14 | private var _cones:Vector.; 15 | 16 | /** 17 | * Creates a new Trident object. 18 | * 19 | * @param radius The radius of the trident axes. Default is 500. 20 | */ 21 | public function Trident(radius:int = 500, hasNegativeTrident:Boolean = false) 22 | { 23 | // lines 24 | _lines = new Vector.(); 25 | _lines.push(new LineSegment(new WireframeMaterial(0xFF0000), new Vector3D(), new Vector3D(radius, 0, 0))); 26 | _lines.push(new LineSegment(new WireframeMaterial(0x00FF00), new Vector3D(), new Vector3D(0, radius, 0))); 27 | _lines.push(new LineSegment(new WireframeMaterial(0x0000FF), new Vector3D(), new Vector3D(0, 0, radius))); 28 | if (hasNegativeTrident) 29 | { 30 | _lines.push(new LineSegment(new WireframeMaterial(0x660000), new Vector3D(), new Vector3D(-radius, 0, 0))); 31 | _lines.push(new LineSegment(new WireframeMaterial(0x006600), new Vector3D(), new Vector3D(0, -radius, 0))); 32 | _lines.push(new LineSegment(new WireframeMaterial(0x000066), new Vector3D(), new Vector3D(0, 0, -radius))); 33 | } 34 | 35 | for each (var _line:LineSegment in _lines) 36 | addChild(_line); 37 | 38 | // cones 39 | _cones = new Vector.(); 40 | 41 | var xCone:Cone = new Cone(new WireframeMaterial(0xFF0000), 10, 20, 4); 42 | xCone.x = radius; 43 | xCone.rotationZ = 90; 44 | _cones.push(addChild(xCone)); 45 | 46 | var yCone:Cone = new Cone(new WireframeMaterial(0x00FF00), 10, 20, 4); 47 | yCone.y = radius; 48 | yCone.rotationX = -180; 49 | _cones.push(addChild(yCone)); 50 | 51 | var zCone:Cone = new Cone(new WireframeMaterial(0x0000FF), 10, 20, 4); 52 | zCone.z = radius; 53 | zCone.rotationX = -90; 54 | _cones.push(addChild(zCone)); 55 | 56 | if (hasNegativeTrident) 57 | { 58 | var _xCone:Cone = new Cone(new WireframeMaterial(0x660000), 10, 20, 4); 59 | _xCone.x = -radius; 60 | _xCone.rotationZ = -90; 61 | _cones.push(addChild(_xCone)); 62 | 63 | var _yCone:Cone = new Cone(new WireframeMaterial(0x006600), 10, 20, 4); 64 | _yCone.y = -radius; 65 | _cones.push(addChild(_yCone)); 66 | 67 | var _zCone:Cone = new Cone(new WireframeMaterial(0x000066), 10, 20, 4); 68 | _zCone.z = -radius; 69 | _zCone.rotationX = 90; 70 | _cones.push(addChild(_zCone)); 71 | } 72 | 73 | for each (var _cone:Cone in _cones) 74 | { 75 | _cone.bothsides = true; 76 | _cone.mouseEnabled = false; 77 | } 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/away3dlite/lights/DirectionalLight3D.as: -------------------------------------------------------------------------------- 1 | package away3dlite.lights 2 | { 3 | import away3dlite.arcane; 4 | 5 | import flash.geom.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * @author robbateman 11 | */ 12 | public class DirectionalLight3D extends AbstractLight3D 13 | { 14 | private const _TO_DEGREES:Number = 180/Math.PI; 15 | private var _ambient:Number = 0.5; 16 | private var _diffuse:Number = 0.5; 17 | private var _specular:Number = 1; 18 | 19 | private var _direction:Vector3D; 20 | private var _diffuseTransform:Matrix3D = new Matrix3D(); 21 | private var _specularTransform:Matrix3D = new Matrix3D(); 22 | private var _diffuseTransformDirty:Boolean; 23 | 24 | /** 25 | * 26 | */ 27 | public function get ambient():Number 28 | { 29 | return _ambient; 30 | } 31 | 32 | public function set ambient(val:Number):void 33 | { 34 | if (_ambient == val) 35 | return; 36 | 37 | _ambient = val; 38 | } 39 | 40 | /** 41 | * 42 | */ 43 | public function get diffuse():Number 44 | { 45 | return _diffuse; 46 | } 47 | 48 | public function set diffuse(val:Number):void 49 | { 50 | if (_diffuse == val) 51 | return; 52 | 53 | _diffuse = val; 54 | } 55 | 56 | /** 57 | * 58 | */ 59 | public function get specular():Number 60 | { 61 | return _specular; 62 | } 63 | 64 | public function set specular(val:Number):void 65 | { 66 | if (_specular == val) 67 | return; 68 | 69 | _specular = val; 70 | } 71 | 72 | /** 73 | * 74 | */ 75 | public function get direction():Vector3D 76 | { 77 | return _direction; 78 | } 79 | 80 | public function set direction(val:Vector3D):void 81 | { 82 | if (_direction == val) 83 | return; 84 | 85 | _direction = val; 86 | 87 | _diffuseTransformDirty = true; 88 | } 89 | 90 | public function get diffuseTransform():Matrix3D 91 | { 92 | if (_diffuseTransformDirty) { 93 | 94 | _diffuseTransformDirty = false; 95 | 96 | _direction.normalize(); 97 | 98 | var nx:Number = _direction.x; 99 | var ny:Number = _direction.y; 100 | var mod:Number = Math.sqrt(nx*nx + ny*ny); 101 | 102 | _diffuseTransform.identity(); 103 | 104 | if (mod) 105 | _diffuseTransform.prependRotation(-Math.acos(-_direction.z)*_TO_DEGREES, new Vector3D(ny/mod, -nx/mod, 0)); 106 | else 107 | _diffuseTransform.prependRotation(-Math.acos(-_direction.z)*_TO_DEGREES, new Vector3D(0, 1, 0)); 108 | } 109 | 110 | return _diffuseTransform; 111 | } 112 | 113 | public function get specularTransform():Matrix3D 114 | { 115 | var halfVector:Vector3D = new Vector3D(_camera.sceneMatrix3D.rawData[8], _camera.sceneMatrix3D.rawData[9], _camera.sceneMatrix3D.rawData[10]); 116 | halfVector = halfVector.add(_direction); 117 | halfVector.normalize(); 118 | 119 | var nx:Number = halfVector.x; 120 | var ny:Number = halfVector.y; 121 | var mod:Number = Math.sqrt(nx*nx + ny*ny); 122 | 123 | _specularTransform.identity(); 124 | _specularTransform.prependRotation(Math.acos(-halfVector.z)*_TO_DEGREES, new Vector3D(-ny/mod, nx/mod, 0)); 125 | 126 | return _specularTransform; 127 | } 128 | /** 129 | * 130 | */ 131 | public function DirectionalLight3D() 132 | { 133 | 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/away3dlite/core/clip/RectangleClipping.as: -------------------------------------------------------------------------------- 1 | package away3dlite.core.clip 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.base.*; 5 | 6 | use namespace arcane; 7 | 8 | /** 9 | * Rectangle clipping 10 | */ 11 | public class RectangleClipping extends Clipping 12 | { 13 | /** @private */ 14 | arcane override function collectFaces(mesh:Mesh, faces:Vector.):void 15 | { 16 | _faces = mesh._faces; 17 | _uvtData = mesh._uvtData; 18 | _screenVertices = mesh._screenVertices; 19 | 20 | _screenVerticesCull = new Vector.(); 21 | _index = _screenVerticesCull.length = _screenVertices.length/2; 22 | _screenVerticesCull.fixed = true; 23 | 24 | while (_index--) { 25 | _indexX = _index*2; 26 | _indexY = _indexX + 1; 27 | _indexZ = _index*3 + 2; 28 | 29 | if (_uvtData[_indexZ] < 0) { 30 | _screenVerticesCull[_index] += 0x10000; 31 | } else { 32 | if (_screenVertices[_indexX] < _minX) 33 | _screenVerticesCull[_index] += 0x1000; 34 | else if (_screenVertices[_indexX] > _maxX) 35 | _screenVerticesCull[_index] += 0x100; 36 | 37 | if (_screenVertices[_indexY] < _minY) 38 | _screenVerticesCull[_index] += 0x10; 39 | else if (_screenVertices[_indexY] > _maxY) 40 | _screenVerticesCull[_index] += 0x1; 41 | } 42 | } 43 | 44 | for each(_face in _faces) { 45 | if (mesh.bothsides || _screenVertices[_face.x0]*(_screenVertices[_face.y2] - _screenVertices[_face.y1]) + _screenVertices[_face.x1]*(_screenVertices[_face.y0] - _screenVertices[_face.y2]) + _screenVertices[_face.x2]*(_screenVertices[_face.y1] - _screenVertices[_face.y0]) > 0) { 46 | 47 | if (_face.i3) { 48 | _cullTotal = 4; 49 | _cullCount = _screenVerticesCull[_face.i0] + _screenVerticesCull[_face.i1] + _screenVerticesCull[_face.i2] + _screenVerticesCull[_face.i3]; 50 | } else { 51 | _cullTotal = 3; 52 | _cullCount = _screenVerticesCull[_face.i0] + _screenVerticesCull[_face.i1] + _screenVerticesCull[_face.i2]; 53 | } 54 | 55 | if (!(_cullCount >> 16) && (_cullCount >> 12 & 15) < _cullTotal && (_cullCount >> 8 & 15) < _cullTotal && (_cullCount >> 4 & 15) < _cullTotal && (_cullCount & 15) < _cullTotal) 56 | faces[faces.length] = _face; 57 | } 58 | } 59 | } 60 | 61 | /** 62 | * Creates a new RectangleClipping object. 63 | * 64 | * @param minX Minimum allowed x value for primitives. 65 | * @param maxX Maximum allowed x value for primitives. 66 | * @param minY Minimum allowed y value for primitives. 67 | * @param maxY Maximum allowed y value for primitives. 68 | * @param minZ Minimum allowed z value for primitives. 69 | * @param maxZ Maximum allowed z value for primitives. 70 | */ 71 | public function RectangleClipping(minX:Number = -100000, maxX:Number = 100000, minY:Number = -100000, maxY:Number = 100000, minZ:Number = -100000, maxZ:Number = 100000) 72 | { 73 | super(minX, maxX, minY, maxY, minZ, maxZ); 74 | } 75 | 76 | public override function clone(object:Clipping = null):Clipping 77 | { 78 | var clipping:RectangleClipping = (object as RectangleClipping) || new RectangleClipping(); 79 | 80 | super.clone(clipping); 81 | 82 | return clipping; 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /src/away3dlite/primitives/RegularPolygon.as: -------------------------------------------------------------------------------- 1 | package away3dlite.primitives { import away3dlite.arcane; import away3dlite.core.base.*; import away3dlite.materials.*; use namespace arcane; /** * Creates a regular polygon. */ public class RegularPolygon extends AbstractPrimitive { private var _radius:Number = 100; private var _segmentsW:int = 8; private var _yUp:Boolean = true; /** * @inheritDoc */ protected override function buildPrimitive():void { super.buildPrimitive(); var i:int = 0; _yUp? _vertices.push(0, 0, 0) : _vertices.push(0, 0, 0); _uvtData.push(0.5, 0.5, 1); for (i = 0; i < _segmentsW; ++i) { var verangle:Number = 2*Math.PI*i/_segmentsW; var x:Number = _radius*Math.cos(verangle); var y:Number = _radius*Math.sin(verangle); _yUp? _vertices.push(x, 0, y) : _vertices.push(x, y, 0); _uvtData.push(0.5 - 0.5*x/_radius, 0.5 + 0.5*y/_radius, 1); } for (i = 0; i < _segmentsW; ++i) { _indices.push(0, i + 1, (i + 1 + _segmentsW) % (_segmentsW) + 1); _faceLengths.push(3); } } /** * Defines the radius of the regular polygon. Defaults to 100. */ public function get radius():Number { return _radius; } public function set radius(val:Number):void { if (_radius == val) return; _radius = val; _primitiveDirty = true; } /** * Defines the number of horizontal segments that make up the regular polygon. Defaults to 8. */ public function get segmentsW():int { return _segmentsW; } public function set segmentsW(val:int):void { if (_segmentsW == val) return; _segmentsW = val; _primitiveDirty = true; } /** * Defines whether the coordinates of the regular polygon points use a yUp orientation (true) or a zUp orientation (false). Defaults to true. */ public function get yUp():Boolean { return _yUp; } public function set yUp(val:Boolean):void { if (_yUp == val) return; _yUp = val; _primitiveDirty = true; } /** * Creates a new RegularPolygon object. * * @param material Defines the global material used on the faces in the regular polygon. * @param radius Defines the radius of the regular polygon base. * @param segmentsW Defines the number of horizontal segments that make up the regular polygon. * @param yUp Defines whether the coordinates of the regular polygon points use a yUp orientation (true) or a zUp orientation (false). */ public function RegularPolygon(material:Material = null, radius:Number = 100, segmentsW:int = 8, yUp:Boolean = true) { super(material); _radius = radius; _segmentsW = segmentsW; _yUp = yUp; type = "RegularPolygon"; url = "primitive"; } /** * Duplicates the regular polygon properties to another RegularPolygon object. * * @param object [optional] The new object instance into which all properties are copied. The default is RegularPolygon. * @return The new object instance with duplicated properties applied. */ public override function clone(object:Object3D = null):Object3D { var regularpolygon:RegularPolygon = (object as RegularPolygon) || new RegularPolygon(); super.clone(regularpolygon); regularpolygon.radius = _radius; regularpolygon.segmentsW = _segmentsW; regularpolygon.yUp = _yUp; regularpolygon._primitiveDirty = false; return regularpolygon; } } } -------------------------------------------------------------------------------- /src/away3dlite/materials/Material.as: -------------------------------------------------------------------------------- 1 | package away3dlite.materials 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.cameras.*; 5 | import away3dlite.containers.*; 6 | import away3dlite.core.base.*; 7 | import away3dlite.events.*; 8 | 9 | import flash.events.*; 10 | import flash.display.*; 11 | 12 | use namespace arcane; 13 | 14 | /** 15 | * Dispatched when the material becomes visible in a view. 16 | * 17 | * @eventType away3dlite.events.MaterialEvent 18 | */ 19 | [Event(name="materialActivated",type="away3dlite.events.MaterialEvent")] 20 | 21 | /** 22 | * Dispatched when the material becomes invisible in a view. 23 | * 24 | * @eventType away3dlite.events.MaterialEvent 25 | */ 26 | [Event(name="materialDeactivated",type="away3dlite.events.MaterialEvent")] 27 | 28 | /** 29 | * Base material class. 30 | */ 31 | public class Material extends EventDispatcher 32 | { 33 | /** @private */ 34 | arcane var _id:Vector. = new Vector.(); 35 | /** @private */ 36 | arcane var _faceCount:Vector. = new Vector.(); 37 | /** @private */ 38 | arcane function notifyActivate(scene:Scene3D):void 39 | { 40 | scene; 41 | 42 | if (!hasEventListener(MaterialEvent.MATERIAL_ACTIVATED)) 43 | return; 44 | 45 | if (_materialactivated == null) 46 | _materialactivated = new MaterialEvent(MaterialEvent.MATERIAL_ACTIVATED, this); 47 | 48 | dispatchEvent(_materialactivated); 49 | } 50 | /** @private */ 51 | arcane function notifyDeactivate(scene:Scene3D):void 52 | { 53 | scene; 54 | 55 | if (!hasEventListener(MaterialEvent.MATERIAL_DEACTIVATED)) 56 | return; 57 | 58 | if (_materialdeactivated == null) 59 | _materialdeactivated = new MaterialEvent(MaterialEvent.MATERIAL_DEACTIVATED, this); 60 | 61 | dispatchEvent(_materialdeactivated); 62 | } 63 | /** @private */ 64 | arcane function updateMaterial(source:Mesh, camera:Camera3D):void 65 | { 66 | 67 | } 68 | 69 | private const DEBUG_STROKE:GraphicsStroke = new GraphicsStroke(1, false, "normal", "none", "round", 0, new GraphicsSolidFill(0xFF00FF)); 70 | private var _debug:Boolean = false; 71 | private var _materialactivated:MaterialEvent; 72 | private var _materialdeactivated:MaterialEvent; 73 | 74 | /** @private */ 75 | protected var _graphicsStroke:GraphicsStroke = new GraphicsStroke(); 76 | /** @private */ 77 | protected var _graphicsBitmapFill:GraphicsBitmapFill = new GraphicsBitmapFill(); 78 | /** @private */ 79 | protected var _graphicsEndFill:GraphicsEndFill = new GraphicsEndFill(); 80 | /** @private */ 81 | protected var _triangles:GraphicsTrianglePath; 82 | /** @private */ 83 | public var graphicsData:Vector.; 84 | /** @private */ 85 | public var trianglesIndex:int; 86 | 87 | /** 88 | * Switches on the debug outlines around each face drawn with the material. Defaults to false. 89 | */ 90 | public function get debug():Boolean 91 | { 92 | return _debug; 93 | } 94 | public function set debug(val:Boolean):void 95 | { 96 | if (_debug == val) 97 | return; 98 | 99 | _debug = val; 100 | 101 | graphicsData.fixed = false; 102 | 103 | if(_debug) { 104 | graphicsData.shift(); 105 | graphicsData.unshift(DEBUG_STROKE); 106 | } else { 107 | graphicsData.shift(); 108 | graphicsData.unshift(_graphicsStroke); 109 | } 110 | 111 | graphicsData.fixed = true; 112 | } 113 | 114 | /** 115 | * Creates a new Material object. 116 | */ 117 | public function Material() 118 | { 119 | 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /src/away3dlite/animators/bones/Channel.as: -------------------------------------------------------------------------------- 1 | package away3dlite.animators.bones 2 | { 3 | import away3dlite.containers.*; 4 | import away3dlite.core.base.*; 5 | 6 | /** 7 | * Stores the varying transformations of a single Bone or Object3D object over the dureation of a bones animation 8 | * 9 | * @see away3dlite.animators.BonesAnimator 10 | */ 11 | public class Channel 12 | { 13 | private var i:int; 14 | private var _index:int; 15 | private var _length:int; 16 | private var _oldlength:int; 17 | 18 | public var name:String; 19 | public var target:Object3D; 20 | 21 | public var type:Array; 22 | 23 | public var param:Array; 24 | public var inTangent:Array; 25 | public var outTangent:Array; 26 | 27 | public var times:Array; 28 | public var interpolations:Array; 29 | 30 | public function Channel(name:String):void 31 | { 32 | this.name = name; 33 | 34 | type = []; 35 | 36 | param = []; 37 | inTangent = []; 38 | outTangent = []; 39 | times = []; 40 | 41 | interpolations = []; 42 | } 43 | 44 | /** 45 | * Updates the channel's target with the data point at the given time in seconds. 46 | * 47 | * @param time Defines the time in seconds of the playhead of the animation. 48 | * @param interpolate [optional] Defines whether the animation interpolates between channel points Defaults to true. 49 | */ 50 | public function update(time:Number, interpolate:Boolean = true):void 51 | { 52 | if (!target) 53 | return; 54 | 55 | i = type.length; 56 | 57 | if (time < times[0]) { 58 | while (i--) { 59 | if (type[i] == "transform") { 60 | target.transform.matrix3D = param[0][i]; 61 | } else if (type[i] == "visibility") { 62 | target.visible = param[0][i] > 0; 63 | } else { 64 | target[type[i]] = param[0][i]; 65 | } 66 | } 67 | } else if (time > times[int(times.length-1)]) { 68 | while (i--) { 69 | if (type[i] == "transform") { 70 | target.transform.matrix3D = param[int(times.length-1)][i]; 71 | } else if (type[i] == "visibility") { 72 | target.visible = param[int(times.length-1)][i] > 0; 73 | } else { 74 | target[type[i]] = param[int(times.length-1)][i]; 75 | } 76 | } 77 | } else { 78 | _index = _length = _oldlength = times.length - 1; 79 | 80 | while (_length > 1) 81 | { 82 | _oldlength = _length; 83 | _length >>= 1; 84 | 85 | if (times[_index - _length] > time) { 86 | _index -= _length; 87 | _length = _oldlength - _length; 88 | } 89 | } 90 | 91 | _index--; 92 | 93 | while (i--) { 94 | if (type[i] == "transform") { 95 | target.transform.matrix3D = param[_index][i]; 96 | } else if (type[i] == "visibility") { 97 | target.visible = param[_index][i] > 0; 98 | } else { 99 | if (interpolate) 100 | target[type[i]] = ((time - times[_index]) * param[int(_index + 1)][i] + (times[int(_index + 1)] - time) * param[_index][i]) / (times[int(_index + 1)] - times[_index]); 101 | else 102 | target[type[i]] = param[_index][i]; 103 | } 104 | } 105 | } 106 | } 107 | 108 | public function clone(object:ObjectContainer3D):Channel 109 | { 110 | var channel:Channel = new Channel(name); 111 | 112 | channel.target = object.getChildByName(name) as Object3D; 113 | channel.type = type.concat(); 114 | channel.param = param.concat(); 115 | channel.inTangent = inTangent.concat(); 116 | channel.outTangent = outTangent.concat(); 117 | channel.times = times.concat(); 118 | channel.interpolations = interpolations.concat(); 119 | 120 | return channel; 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/away3dlite/animators/bones/Bone.as: -------------------------------------------------------------------------------- 1 | package away3dlite.animators.bones 2 | { 3 | import away3dlite.containers.*; 4 | import away3dlite.arcane; 5 | import away3dlite.core.base.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * ObjectContainer3D representing a bone and joint in a bones animation skeleton. 11 | * 12 | * @see away3dlite.animators.BonesAnimator 13 | */ 14 | public class Bone extends ObjectContainer3D 15 | { 16 | /** 17 | * the joint object of the bone 18 | */ 19 | public var joint:ObjectContainer3D; 20 | 21 | /** 22 | * Collada 3.05B id value 23 | */ 24 | public var boneId:String; 25 | 26 | /** 27 | * Defines the euler angle of rotation of the 3d object around the x-axis, relative to the local coordinates of the parent ObjectContainer3D. 28 | */ 29 | public function get jointRotationX():Number 30 | { 31 | return joint.rotationX; 32 | } 33 | 34 | public function set jointRotationX(rot:Number):void 35 | { 36 | joint.rotationX = rot; 37 | } 38 | 39 | /** 40 | * Defines the euler angle of rotation of the 3d object around the y-axis, relative to the local coordinates of the parent ObjectContainer3D. 41 | */ 42 | public function get jointRotationY():Number 43 | { 44 | return joint.rotationY; 45 | } 46 | 47 | public function set jointRotationY(rot:Number):void 48 | { 49 | joint.rotationY = rot; 50 | } 51 | 52 | /** 53 | * Defines the euler angle of rotation of the 3d object around the z-axis, relative to the local coordinates of the parent ObjectContainer3D. 54 | */ 55 | public function get jointRotationZ():Number 56 | { 57 | return joint.rotationZ; 58 | } 59 | 60 | public function set jointRotationZ(rot:Number):void 61 | { 62 | joint.rotationZ = rot; 63 | } 64 | 65 | /** 66 | * Defines the scale of the 3d object along the x-axis, relative to local coordinates. 67 | */ 68 | public function get jointScaleX():Number 69 | { 70 | return joint.scaleX; 71 | } 72 | 73 | public function set jointScaleX(scale:Number):void 74 | { 75 | joint.scaleX = scale; 76 | } 77 | 78 | /** 79 | * Defines the scale of the 3d object along the y-axis, relative to local coordinates. 80 | */ 81 | public function get jointScaleY():Number 82 | { 83 | return joint.scaleY; 84 | } 85 | 86 | public function set jointScaleY(scale:Number):void 87 | { 88 | joint.scaleY = scale; 89 | } 90 | 91 | /** 92 | * Defines the scale of the 3d object along the z-axis, relative to local coordinates. 93 | */ 94 | public function get jointScaleZ():Number 95 | { 96 | return joint.scaleZ; 97 | } 98 | 99 | public function set jointScaleZ(scale:Number):void 100 | { 101 | joint.scaleZ = scale; 102 | } 103 | 104 | /** 105 | * Creates a new Bone object. 106 | */ 107 | public function Bone() 108 | { 109 | super(); 110 | 111 | //create the joint for the bone 112 | addChild(joint = new ObjectContainer3D()); 113 | } 114 | 115 | /** 116 | * Duplicates the 3d object's properties to another Bone object 117 | * 118 | * @param object [optional] The new object instance into which all properties are copied. The default is Bone. 119 | * @return The new object instance with duplicated properties applied. 120 | */ 121 | public override function clone(object:Object3D = null):Object3D 122 | { 123 | var bone:Bone = (object as Bone) || new Bone(); 124 | super.clone(bone); 125 | 126 | bone.joint = bone.children[0] as ObjectContainer3D; 127 | 128 | return bone; 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/away3dlite/loaders/data/MaterialData.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.data 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.base.*; 5 | import away3dlite.materials.*; 6 | 7 | import flash.display.BitmapData; 8 | 9 | use namespace arcane; 10 | 11 | /** 12 | * Data class for the material data of a face. 13 | * 14 | * @see away3dlite.loaders.data.FaceData 15 | */ 16 | public class MaterialData 17 | { 18 | private var _material:Material; 19 | 20 | /** 21 | * String representing a texture material. 22 | */ 23 | public static const TEXTURE_MATERIAL:String = "textureMaterial"; 24 | 25 | /** 26 | * String representing a shaded material. 27 | */ 28 | public static const SHADING_MATERIAL:String = "shadingMaterial"; 29 | 30 | /** 31 | * String representing a color material. 32 | */ 33 | public static const COLOR_MATERIAL:String = "colorMaterial"; 34 | 35 | /** 36 | * String representing a wireframe material. 37 | */ 38 | public static const WIREFRAME_MATERIAL:String = "wireframeMaterial"; 39 | 40 | /** 41 | * The name of the material used as a unique reference. 42 | */ 43 | public var name:String; 44 | 45 | /** 46 | * Optional alpha of the material. 47 | */ 48 | public var alpha:Number; 49 | 50 | /** 51 | * Optional ambient color of the material. 52 | */ 53 | public var ambientColor:uint; 54 | 55 | /** 56 | * Optional diffuse color of the material. 57 | */ 58 | public var diffuseColor:uint; 59 | 60 | /** 61 | * Optional specular color of the material. 62 | */ 63 | public var specularColor:uint; 64 | 65 | /** 66 | * Optional shininess of the material. 67 | */ 68 | public var shininess:Number; 69 | 70 | /** 71 | * Reference to the filename of the texture image. 72 | */ 73 | public var textureFileName:String; 74 | 75 | /** 76 | * Reference to the bitmapData object of the texture image. 77 | */ 78 | public var textureBitmap:BitmapData; 79 | 80 | /** 81 | * defines the material object of the resulting material. 82 | */ 83 | public function get material():Material 84 | { 85 | return _material; 86 | } 87 | 88 | public function set material(val:Material):void 89 | { 90 | if (_material == val) 91 | return; 92 | 93 | _material = val; 94 | 95 | if (_material is BitmapMaterial) 96 | textureBitmap = (_material as BitmapMaterial).bitmap; 97 | 98 | var mesh:Mesh; 99 | for each (mesh in meshes) 100 | mesh.material = _material; 101 | 102 | var face:Face; 103 | 104 | for each (face in faces) { 105 | face.mesh._faceMaterials[face.faceIndex] = _material; 106 | face.mesh._materialsDirty = true; 107 | } 108 | } 109 | 110 | /** 111 | * String representing the material type. 112 | */ 113 | public var materialType:String = WIREFRAME_MATERIAL; 114 | 115 | /** 116 | * Array of indexes representing the elements that use the material. 117 | */ 118 | public var faces:Vector. = new Vector.(); 119 | 120 | /** 121 | * Array of indexes representing the meshes that use the material. 122 | */ 123 | public var meshes:Vector. = new Vector.(); 124 | 125 | public function clone(targetObj:Object3D):MaterialData 126 | { 127 | var cloneMatData:MaterialData = targetObj.materialLibrary.addMaterial(name); 128 | 129 | cloneMatData.materialType = materialType; 130 | cloneMatData.ambientColor = ambientColor; 131 | cloneMatData.diffuseColor = diffuseColor; 132 | cloneMatData.shininess = shininess; 133 | cloneMatData.specularColor = specularColor; 134 | cloneMatData.textureBitmap = textureBitmap; 135 | cloneMatData.textureFileName = textureFileName; 136 | cloneMatData.material = material; 137 | /* 138 | for each(var element:Element in elements) 139 | { 140 | var parentGeometry:Geometry = element.parent; 141 | var correspondingElement:Element = parentGeometry.cloneElementDictionary[element]; 142 | cloneMatData.elements.push(correspondingElement); 143 | } 144 | */ 145 | return cloneMatData; 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /src/away3dlite/materials/MovieMaterial.as: -------------------------------------------------------------------------------- 1 | package away3dlite.materials 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.containers.*; 5 | 6 | import flash.events.Event; 7 | import flash.display.*; 8 | import flash.geom.*; 9 | 10 | use namespace arcane; 11 | 12 | public class MovieMaterial extends BitmapMaterial 13 | { 14 | /** @private */ 15 | arcane override function notifyActivate(scene:Scene3D):void 16 | { 17 | super.notifyActivate(scene); 18 | scene._broadcaster.addEventListener(Event.ENTER_FRAME, onEnterFrame); 19 | onEnterFrame(); 20 | } 21 | /** @private */ 22 | arcane override function notifyDeactivate(scene:Scene3D):void 23 | { 24 | super.notifyActivate(scene); 25 | scene._broadcaster.removeEventListener(Event.ENTER_FRAME, onEnterFrame); 26 | } 27 | 28 | private var _transparent:Boolean; 29 | private var _movie:Sprite; 30 | private var _movieRect:Rectangle; 31 | private var _rect:Rectangle; 32 | private var _drawRect:Rectangle; 33 | private var _bitmapDirty:Boolean; 34 | 35 | private function onEnterFrame(event:Event = null):void 36 | { 37 | if (autoUpdate) 38 | update(); 39 | } 40 | 41 | private function updateBitmap():void 42 | { 43 | _bitmapDirty = false; 44 | 45 | _drawRect = _rect || _movieRect; 46 | 47 | if (_drawRect.width == 0 || _drawRect.height == 0) 48 | _drawRect = new Rectangle(0, 0, 256, 256); 49 | 50 | _graphicsBitmapFill.bitmapData = new BitmapData(int(_drawRect.width + 0.99), int(_drawRect.height + 0.99), _transparent, 0); 51 | } 52 | 53 | /** 54 | * Indicates whether the texture bitmap is updated on every frame 55 | */ 56 | public var autoUpdate:Boolean; 57 | 58 | /** 59 | * Defines the transparent property of the texture bitmap created from the movie 60 | * 61 | * @see movie 62 | */ 63 | public function get transparent():Boolean 64 | { 65 | return _transparent; 66 | } 67 | 68 | public function set transparent(val:Boolean):void 69 | { 70 | _transparent = val; 71 | 72 | _bitmapDirty = true; 73 | } 74 | 75 | /** 76 | * Defines the movieclip used for rendering the material 77 | */ 78 | public function get movie():Sprite 79 | { 80 | return _movie; 81 | } 82 | 83 | public function set movie(val:Sprite):void 84 | { 85 | if (_movie == val) 86 | return; 87 | 88 | //if (val && val.parent) 89 | // val.parent.removeChild(val); 90 | 91 | _movie = val; 92 | 93 | _movieRect = _movie.getBounds(_movie); 94 | 95 | _bitmapDirty = true; 96 | 97 | if (!autoUpdate) 98 | update(); 99 | } 100 | 101 | /** 102 | * Defines the rectangle of the movie to be rendered into the texture bitmap. 103 | * 104 | * @see movie 105 | */ 106 | public function get rect():Rectangle 107 | { 108 | return _rect; 109 | } 110 | 111 | public function set rect(val:Rectangle):void 112 | { 113 | _rect = val; 114 | 115 | _bitmapDirty = true; 116 | } 117 | 118 | public function MovieMaterial(movie:Sprite, rect:Rectangle = null, autoUpdate:Boolean = true, transparent:Boolean = true) 119 | { 120 | this.autoUpdate = autoUpdate; 121 | this.movie = movie; 122 | this.rect = rect; 123 | this.transparent = transparent; 124 | } 125 | 126 | /** 127 | * Manually updates the texture bitmap with the current frame of the movie display object. 128 | * Automatically triggered unless autoUpdate is set to false. 129 | * 130 | * @see movie 131 | * @see autoUpdate 132 | */ 133 | public function update():void 134 | { 135 | if (_bitmapDirty) 136 | updateBitmap(); 137 | 138 | var r:Rectangle = _graphicsBitmapFill.bitmapData.rect; 139 | var m:Matrix = new Matrix(_movie.scaleX, 0, 0, _movie.scaleY, -_drawRect.x, -_drawRect.y); 140 | 141 | _graphicsBitmapFill.bitmapData.fillRect(r, 0x000000); 142 | _graphicsBitmapFill.bitmapData.draw(_movie, m, _movie.transform.colorTransform, _movie.blendMode, r); 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /src/away3dlite/events/MouseEvent3D.as: -------------------------------------------------------------------------------- 1 | package away3dlite.events 2 | { 3 | import flash.geom.Vector3D; 4 | import away3dlite.materials.Material; 5 | import away3dlite.containers.*; 6 | import away3dlite.core.base.*; 7 | 8 | import flash.events.Event; 9 | 10 | /** 11 | * Passed as a parameter when a 3d mouse event occurs 12 | */ 13 | public class MouseEvent3D extends Event 14 | { 15 | /** 16 | * Defines the value of the type property of a mouseOver3d event object. 17 | */ 18 | public static const MOUSE_OVER:String = "mouseOver3d"; 19 | 20 | /** 21 | * Defines the value of the type property of a mouseOut3d event object. 22 | */ 23 | public static const MOUSE_OUT:String = "mouseOut3d"; 24 | 25 | /** 26 | * Defines the value of the type property of a mouseUp3d event object. 27 | */ 28 | public static const MOUSE_UP:String = "mouseUp3d"; 29 | 30 | /** 31 | * Defines the value of the type property of a mouseDown3d event object. 32 | */ 33 | public static const MOUSE_DOWN:String = "mouseDown3d"; 34 | 35 | /** 36 | * Defines the value of the type property of a mouseMove3d event object. 37 | */ 38 | public static const MOUSE_MOVE:String = "mouseMove3d"; 39 | 40 | /** 41 | * Defines the value of the type property of a rollOver3d event object. 42 | */ 43 | public static const ROLL_OVER:String = "rollOver3d"; 44 | 45 | /** 46 | * Defines the value of the type property of a rollOut3d event object. 47 | */ 48 | public static const ROLL_OUT:String = "rollOut3d"; 49 | 50 | /** 51 | * The horizontal coordinate at which the event occurred in view coordinates. 52 | */ 53 | public var screenX:Number; 54 | 55 | /** 56 | * The vertical coordinate at which the event occurred in view coordinates. 57 | */ 58 | public var screenY:Number; 59 | 60 | /** 61 | * The xyz coordinate at which the event occurred in global scene coordinates. 62 | */ 63 | public var scenePosition:Vector3D; 64 | 65 | /** 66 | * The view object inside which the event took place. 67 | */ 68 | public var view:View3D; 69 | 70 | /** 71 | * The 3d object inside which the event took place. 72 | */ 73 | public var object:Object3D; 74 | 75 | /** 76 | * The material of the 3d element inside which the event took place. 77 | */ 78 | public var material:Material; 79 | 80 | /** 81 | * The uvt coordinate inside the triangle where the event took place. 82 | */ 83 | public var uvt:Vector3D; 84 | 85 | /** 86 | * Indicates whether the Control key is active (true) or inactive (false). 87 | */ 88 | public var ctrlKey:Boolean; 89 | 90 | /** 91 | * Indicates whether the Shift key is active (true) or inactive (false). 92 | */ 93 | public var shiftKey:Boolean; 94 | 95 | /** 96 | * Indicates the face that received the mouse event. 97 | */ 98 | public var face:Face; 99 | 100 | /** 101 | * Creates a new MouseEvent3D object. 102 | * 103 | * @param type The type of the event. Possible values are: MouseEvent3D.MOUSE_OVER, MouseEvent3D.MOUSE_OUT, MouseEvent3D.ROLL_OVER, MouseEvent3D.ROLL_OUT, MouseEvent3D.MOUSE_UP, MouseEvent3D.MOUSE_DOWN and MouseEvent3D.MOUSE_MOVE. 104 | */ 105 | public function MouseEvent3D(type:String) 106 | { 107 | super(type, false, true); 108 | } 109 | 110 | /** 111 | * Creates a copy of the MouseEvent3D object and sets the value of each property to match that of the original. 112 | */ 113 | public override function clone():Event 114 | { 115 | var result:MouseEvent3D = new MouseEvent3D(type); 116 | 117 | if(isDefaultPrevented()) 118 | result.preventDefault(); 119 | 120 | result.face = face; 121 | 122 | result.screenX = screenX; 123 | result.screenY = screenY; 124 | 125 | result.scenePosition = scenePosition; 126 | 127 | result.view = view; 128 | result.object = object; 129 | result.material = material; 130 | result.uvt = uvt; 131 | 132 | result.ctrlKey = ctrlKey; 133 | result.shiftKey = shiftKey; 134 | 135 | return result; 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/away3dlite/animators/MovieMesh.as: -------------------------------------------------------------------------------- 1 | package away3dlite.animators 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.base.*; 5 | import away3dlite.animators.frames.Frame; 6 | 7 | import flash.events.*; 8 | import flash.utils.*; 9 | 10 | use namespace arcane; 11 | 12 | /** 13 | * Animates a series of Frame objects in sequence in a mesh. 14 | */ 15 | public class MovieMesh extends Mesh 16 | { 17 | /* 18 | * Three kinds of animation sequences: 19 | * [1] Normal (sequential, just playing) 20 | * [2] Loop (a loop) 21 | * [3] Stop (stopped, not animating) 22 | */ 23 | public static const ANIM_NORMAL:int = 1; 24 | public static const ANIM_LOOP:int = 2; 25 | public static const ANIM_STOP:int = 4; 26 | private var framesLength:int = 0; 27 | 28 | //Keep track of the current frame number and animation 29 | private var _currentFrame:int = 0; 30 | private var _addFrame:int; 31 | private var _interp:Number = 0; 32 | private var _begin:int; 33 | private var _end:int; 34 | private var _type:int; 35 | private var _ctime:Number = 0; 36 | private var _otime:Number = 0; 37 | 38 | private var labels:Dictionary = new Dictionary(true); 39 | private var _currentLabel:String; 40 | 41 | private function onEnterFrame(event:Event = null):void 42 | { 43 | _ctime = getTimer(); 44 | 45 | var cframe:Frame; 46 | var nframe:Frame; 47 | var i:int = _vertices.length; 48 | 49 | cframe = frames[_currentFrame]; 50 | nframe = frames[(_currentFrame + 1) % framesLength]; 51 | 52 | // TODO : optimize 53 | var _cframe_vertices:Vector. = cframe.vertices; 54 | var _nframe_vertices:Vector. = nframe.vertices; 55 | 56 | while (i--) 57 | _vertices[i] = _cframe_vertices[i] + _interp*(_nframe_vertices[i] - _cframe_vertices[i]); 58 | 59 | if (_type != ANIM_STOP) { 60 | _interp += fps * (_ctime - _otime) / 1000; 61 | 62 | if (_interp > 1) { 63 | _addFrame = int(_interp); 64 | 65 | if (_type == ANIM_LOOP && _currentFrame + _addFrame >= _end) 66 | keyframe = _begin + _currentFrame + _addFrame - _end; 67 | else 68 | keyframe += _addFrame; 69 | 70 | _interp -= _addFrame; 71 | } 72 | } 73 | _otime = _ctime; 74 | } 75 | 76 | /** 77 | * Number of animation frames to display per second 78 | */ 79 | public var fps:int = 24; 80 | 81 | /** 82 | * The array of frames that make up the animation sequence. 83 | */ 84 | public var frames:Vector. = new Vector.(); 85 | 86 | /** 87 | * Creates a new MovieMesh object that provides a "keyframe animation"/"vertex animation"/"mesh deformation" framework for subclass loaders. 88 | */ 89 | public function MovieMesh() 90 | { 91 | super(); 92 | } 93 | 94 | /** 95 | * Adds a new frame to the animation timeline. 96 | */ 97 | public function addFrame(frame:Frame):void 98 | { 99 | var _name:String = frame.name.replace(/[0-9]/g, ""); 100 | 101 | if (!labels[_name]) 102 | labels[_name] = {begin:framesLength, end:framesLength}; 103 | else 104 | ++labels[_name].end; 105 | 106 | frames.push(frame); 107 | 108 | framesLength++; 109 | } 110 | 111 | /** 112 | * Begins a looping sequence in the animation. 113 | * 114 | * @param begin The starting frame position. 115 | * @param end The ending frame position. 116 | */ 117 | public function loop(begin:int, end:int):void 118 | { 119 | if (framesLength > 0) { 120 | _begin = (begin % framesLength); 121 | _end = (end % framesLength); 122 | } else { 123 | _begin = begin; 124 | _end = end; 125 | } 126 | 127 | keyframe = begin; 128 | _type = ANIM_LOOP; 129 | 130 | addEventListener(Event.ENTER_FRAME, onEnterFrame); 131 | } 132 | 133 | /** 134 | * Plays a pre-defined labelled sequence of animation frames. 135 | */ 136 | public function play(label:String = ""):void 137 | { 138 | if (!labels) 139 | return; 140 | 141 | if (_currentLabel != label) { 142 | _currentLabel = label; 143 | loop(labels[label].begin, labels[label].end); 144 | } 145 | 146 | addEventListener(Event.ENTER_FRAME, onEnterFrame); 147 | } 148 | 149 | /** 150 | * Stops the animation. 151 | */ 152 | public function stop():void 153 | { 154 | _type = ANIM_STOP; 155 | 156 | removeEventListener(Event.ENTER_FRAME, onEnterFrame); 157 | } 158 | 159 | /** 160 | * Defines the current keyframe. 161 | */ 162 | public function get keyframe():int 163 | { 164 | return _currentFrame; 165 | } 166 | 167 | public function set keyframe(i:int):void 168 | { 169 | _currentFrame = i % framesLength; 170 | } 171 | } 172 | } -------------------------------------------------------------------------------- /src/away3dlite/containers/Scene3D.as: -------------------------------------------------------------------------------- 1 | package away3dlite.containers 2 | { 3 | import away3dlite.lights.AbstractLight3D; 4 | import away3dlite.arcane; 5 | import away3dlite.cameras.*; 6 | import away3dlite.core.base.*; 7 | import away3dlite.materials.*; 8 | 9 | import flash.geom.*; 10 | import flash.display.*; 11 | 12 | use namespace arcane; 13 | 14 | /** 15 | * The root container of all 3d objects in a single scene 16 | */ 17 | public class Scene3D extends ObjectContainer3D 18 | { 19 | private var _index:int; 20 | 21 | arcane var _id:uint; 22 | /** @private */ 23 | arcane var _broadcaster:Sprite = new Sprite(); 24 | /** @private */ 25 | arcane var _materialsSceneList:Vector. = new Vector.(); 26 | /** @private */ 27 | arcane var _materialsPreviousList:Vector. = new Vector.(); 28 | /** @private */ 29 | arcane var _materialsNextList:Vector. = new Vector.(); 30 | /** @private */ 31 | arcane var _sceneLights:Vector. = new Vector.(); 32 | /** @private */ 33 | arcane function removeSceneMaterial(mat:Material):void 34 | { 35 | 36 | if (!(--mat._faceCount[_id])) { 37 | 38 | _materialsSceneList[mat._id[_id]] = null; 39 | 40 | //reduce the length of the material list if the removed material is at the end 41 | if (mat._id[_id] == _materialsSceneList.length - 1) { 42 | _materialsSceneList.length--; 43 | _materialsNextList.length--; 44 | } 45 | } 46 | } 47 | /** @private */ 48 | arcane function addSceneMaterial(mat:Material):void 49 | { 50 | if (mat._faceCount.length <= _id) 51 | mat._id.length = mat._faceCount.length = _id + 1; 52 | 53 | if (!mat._faceCount[_id]) { 54 | 55 | var i:uint = 0; 56 | var length:uint = _materialsSceneList.length; 57 | while (i < length) { 58 | //add the material to the first available space 59 | if (!_materialsSceneList[i]) { 60 | _materialsSceneList[mat._id[_id] = i] = mat; 61 | break; 62 | } else { 63 | i++; 64 | } 65 | } 66 | //increase the length of the material list if the added material is at the end 67 | if (i == length) { 68 | _materialsSceneList.length++; 69 | _materialsNextList.length++; 70 | _materialsSceneList[mat._id[_id] = i] = mat; 71 | } 72 | } 73 | //this in above conditional causes flex java error 74 | mat._faceCount[_id]++; 75 | } 76 | /** @private */ 77 | arcane function addSceneLight(light:AbstractLight3D):void 78 | { 79 | _sceneLights[_sceneLights.length] = light; 80 | } 81 | /** @private */ 82 | arcane function removeSceneLight(light:AbstractLight3D):void 83 | { 84 | _index = _sceneLights.indexOf(light); 85 | 86 | if (_index != -1) 87 | _sceneLights.splice(_index, 1); 88 | } 89 | /** @private */ 90 | arcane override function project(camera:Camera3D, parentSceneMatrix3D:Matrix3D = null):void 91 | { 92 | _materialsNextList = new Vector.(_materialsNextList.length); 93 | 94 | super.project(camera, parentSceneMatrix3D); 95 | 96 | var i:uint; 97 | var matPrevious:Material; 98 | var matNext:Material; 99 | 100 | if (_materialsPreviousList.length > _materialsNextList.length) 101 | i = _materialsNextList.length = _materialsPreviousList.length; 102 | else 103 | i = _materialsPreviousList.length = _materialsNextList.length; 104 | 105 | while (i--) { 106 | matPrevious = _materialsPreviousList[i]; 107 | matNext = _materialsNextList[i]; 108 | if (matPrevious != matNext) { 109 | if (matPrevious) 110 | matPrevious.notifyDeactivate(this); 111 | if (matNext) 112 | matNext.notifyActivate(this); 113 | } 114 | } 115 | 116 | _materialsPreviousList = _materialsNextList; 117 | } 118 | 119 | private static var _idTotal:uint = 0; 120 | 121 | /** 122 | * Returns the lights of the scene as an array of 3d lights. 123 | */ 124 | public function get sceneLights():Vector. 125 | { 126 | return _sceneLights; 127 | } 128 | 129 | /** 130 | * Creates a new Scene3D object 131 | * 132 | * @param ...childArray An array of 3d objects to be added as children of the container on instatiation. Can contain an initialisation object 133 | */ 134 | public function Scene3D(...childArray) 135 | { 136 | _id = _idTotal++; 137 | 138 | super(); 139 | 140 | for each (var child:Object3D in childArray) 141 | addChild(child); 142 | 143 | _scene = this; 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/away3dlite/animators/BonesAnimator.as: -------------------------------------------------------------------------------- 1 | package away3dlite.animators 2 | { 3 | import flash.utils.*; 4 | import away3dlite.animators.bones.*; 5 | import away3dlite.containers.*; 6 | import away3dlite.core.utils.*; 7 | 8 | /** 9 | * hold the animation information for a bones animation imported from a collada object 10 | * 11 | * @see away3dlite.loaders.Collada 12 | */ 13 | public class BonesAnimator 14 | { 15 | private var _channels:Vector.; 16 | private var _skinControllers:Vector.; 17 | private var _skinController:SkinController; 18 | private var _skinVertices:Vector.; 19 | private var _uniqueSkinVertices:Dictionary; 20 | private var _skinVertex:SkinVertex; 21 | 22 | /** 23 | * Defines wether the animation will loop 24 | */ 25 | public var loop:Boolean; 26 | 27 | /** 28 | * Defines the total length of the animation in seconds 29 | */ 30 | public var length:Number; 31 | 32 | /** 33 | * Defines the start of the animation in seconds 34 | */ 35 | public var start:Number; 36 | 37 | public function BonesAnimator() 38 | { 39 | Debug.trace(" + bonesAnimator"); 40 | _channels = new Vector.(); 41 | _skinControllers = new Vector.(); 42 | _skinVertices = new Vector.(); 43 | _uniqueSkinVertices = new Dictionary(true); 44 | loop = true; 45 | length = 0; 46 | } 47 | 48 | /** 49 | * Updates all channels in the animation with the given time in seconds. 50 | * 51 | * @param time Defines the time in seconds of the playhead of the animation. 52 | * @param interpolate [optional] Defines whether the animation interpolates between channel points Defaults to true. 53 | */ 54 | public function update(time:Number, interpolate:Boolean = true):void 55 | { 56 | if (time > start + length ) { 57 | if (loop) { 58 | time = start + (time - start) % length; 59 | }else{ 60 | time = start + length; 61 | } 62 | } else if (time < start) { 63 | if (loop) { 64 | time = start + (time - start) % length + length; 65 | }else{ 66 | time = start; 67 | } 68 | } 69 | 70 | // ensure vertex list is populated 71 | if (!_skinVertices.fixed) 72 | populateVertices(); 73 | 74 | //update channels 75 | for each (var channel:Channel in _channels) 76 | channel.update(time, interpolate); 77 | 78 | //update skincontrollers 79 | for each(_skinController in _skinControllers) 80 | _skinController.update(); 81 | 82 | //update skinvertices 83 | for each(_skinVertex in _skinVertices) 84 | _skinVertex.update(); 85 | } 86 | 87 | /** 88 | * Populates the skin vertex list from the set of unique vertices 89 | */ 90 | public function populateVertices():void 91 | { 92 | _skinVertices.fixed = false; 93 | for (var obj:Object in _uniqueSkinVertices) 94 | _skinVertices.push(SkinVertex(obj)); 95 | 96 | _skinVertices.fixed = true; 97 | } 98 | 99 | /** 100 | * Clones the animation data into a new BonesAnimator object. 101 | */ 102 | public function clone(object:ObjectContainer3D):BonesAnimator 103 | { 104 | var bonesAnimator:BonesAnimator = new BonesAnimator(); 105 | 106 | bonesAnimator.loop = loop; 107 | bonesAnimator.length = length; 108 | bonesAnimator.start = start; 109 | 110 | for each (var channel:Channel in _channels) 111 | bonesAnimator.addChannel(channel.clone(object)); 112 | 113 | _skinVertices.fixed = false; 114 | return bonesAnimator; 115 | } 116 | 117 | /** 118 | * Adds an animation channel to the animation timeline. 119 | */ 120 | public function addChannel(channel:Channel):void 121 | { 122 | _channels.push(channel); 123 | } 124 | 125 | /** 126 | * Adds a SkinController and all associated SkinVertex objects to the animation. 127 | */ 128 | public function addSkinController(skinController:SkinController):void 129 | { 130 | if (_skinControllers.indexOf(skinController) != -1) 131 | return; 132 | 133 | _skinControllers.push(skinController); 134 | 135 | for each (_skinVertex in skinController.skinVertices) 136 | _uniqueSkinVertices[_skinVertex] = 1; 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/away3dlite/core/render/FastRenderer.as: -------------------------------------------------------------------------------- 1 | package away3dlite.core.render 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.containers.*; 5 | import away3dlite.core.base.*; 6 | import away3dlite.materials.Material; 7 | 8 | import flash.display.*; 9 | 10 | use namespace arcane; 11 | 12 | /** 13 | * @author robbateman 14 | */ 15 | public class FastRenderer extends Renderer 16 | { 17 | private var _i:int; 18 | private var _x:Number; 19 | private var _y:Number; 20 | 21 | private function collectFaces(object:Object3D):void 22 | { 23 | if (!object.visible) 24 | return; 25 | 26 | _mouseEnabledArray.push(_mouseEnabled); 27 | _mouseEnabled = object._mouseEnabled = (_mouseEnabled && object.mouseEnabled); 28 | 29 | if (object is ObjectContainer3D) { 30 | var children:Array = (object as ObjectContainer3D).children; 31 | var child:Object3D; 32 | 33 | if (sortObjects) 34 | children.sortOn("screenZ", 18); 35 | 36 | for each (child in children) { 37 | if(child.layer) 38 | child.layer.graphics.clear(); 39 | 40 | collectFaces(child); 41 | } 42 | } 43 | 44 | var mesh:Mesh = object as Mesh; 45 | 46 | _faces = mesh._faces; 47 | 48 | if(!_faces.length) 49 | return; 50 | 51 | var _mesh_material:Material = mesh.material; 52 | var _mesh_material_graphicsData:Vector. = _mesh_material.graphicsData; 53 | 54 | _mesh_material_graphicsData[_mesh_material.trianglesIndex] = _triangles; 55 | 56 | _ind.fixed = false; 57 | _sort = mesh._sort; 58 | _triangles.culling = mesh._culling; 59 | _uvt = _triangles.uvtData = mesh._uvtData; 60 | _vert = _triangles.vertices = mesh._screenVertices; 61 | _ind.length = mesh._indicesTotal; 62 | _ind.fixed = true; 63 | 64 | if (_view.mouseEnabled && _mouseEnabled) 65 | collectScreenVertices(mesh); 66 | 67 | if (mesh.sortFaces) { 68 | sortFaces(); 69 | } else { 70 | j = _faces.length; 71 | _i = -1; 72 | while (j--) { 73 | _face = _faces[j]; 74 | _ind[int(++_i)] = _face.i0; 75 | _ind[int(++_i)] = _face.i1; 76 | _ind[int(++_i)] = _face.i2; 77 | 78 | if (_face.i3) { 79 | _ind[int(++_i)] = _face.i0; 80 | _ind[int(++_i)] = _face.i2; 81 | _ind[int(++_i)] = _face.i3; 82 | } 83 | } 84 | } 85 | 86 | if(object.layer) 87 | { 88 | object.layer.graphics.drawGraphicsData(_mesh_material_graphicsData); 89 | }else{ 90 | _view_graphics_drawGraphicsData(_mesh_material_graphicsData); 91 | } 92 | 93 | var _faces_length:int = _faces.length; 94 | _view._totalFaces += _faces_length; 95 | _view._renderedFaces += _faces_length; 96 | 97 | _mouseEnabled = _mouseEnabledArray.pop(); 98 | 99 | ++_view._totalObjects; 100 | ++_view._renderedObjects; 101 | } 102 | 103 | private function collectPointFaces(object:Object3D):void 104 | { 105 | if (object is ObjectContainer3D) { 106 | var children:Array = (object as ObjectContainer3D).children; 107 | var child:Object3D; 108 | 109 | for each (child in children) 110 | collectPointFaces(child); 111 | 112 | } else if (object is Mesh) { 113 | var mesh:Mesh = object as Mesh; 114 | 115 | _faces = mesh._faces; 116 | _sort = mesh._sort; 117 | 118 | collectPointFace(_x, _y); 119 | } 120 | } 121 | 122 | /** @private */ 123 | protected override function sortFaces():void 124 | { 125 | super.sortFaces(); 126 | 127 | i = -1; 128 | _i = -1; 129 | while (i++ < 255) { 130 | j = q1[i]; 131 | while (j) { 132 | _face = _faces[j-1]; 133 | _ind[int(++_i)] = _face.i0; 134 | _ind[int(++_i)] = _face.i1; 135 | _ind[int(++_i)] = _face.i2; 136 | 137 | if (_face.i3) { 138 | _ind[int(++_i)] = _face.i0; 139 | _ind[int(++_i)] = _face.i2; 140 | _ind[int(++_i)] = _face.i3; 141 | } 142 | 143 | j = np1[j]; 144 | } 145 | } 146 | } 147 | 148 | /** 149 | * @inheritDoc 150 | */ 151 | public override function getFaceUnderPoint(x:Number, y:Number):Face 152 | { 153 | _x = x; 154 | _y = y; 155 | 156 | collectPointVertices(x, y); 157 | 158 | _screenZ = 0; 159 | 160 | collectPointFaces(_scene); 161 | 162 | return _pointFace; 163 | } 164 | 165 | /** 166 | * Determines whether 3d objects are sorted in the view. Defaults to true. 167 | */ 168 | public var sortObjects:Boolean = true; 169 | 170 | /** 171 | * Creates a new FastRenderer object. 172 | */ 173 | public function FastRenderer() 174 | { 175 | 176 | } 177 | 178 | /** 179 | * @inheritDoc 180 | */ 181 | public override function render():void 182 | { 183 | super.render(); 184 | 185 | collectFaces(_scene); 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /src/away3dlite/templates/Template.as: -------------------------------------------------------------------------------- 1 | package away3dlite.templates 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.cameras.*; 5 | import away3dlite.containers.*; 6 | import away3dlite.debug.*; 7 | 8 | import flash.display.*; 9 | import flash.events.*; 10 | import flash.filters.*; 11 | import flash.text.*; 12 | 13 | use namespace arcane; 14 | 15 | /** 16 | * Base template class. 17 | */ 18 | public class Template extends Sprite 19 | { 20 | /** @private */ 21 | arcane function init():void 22 | { 23 | stage.scaleMode = StageScaleMode.NO_SCALE; 24 | stage.quality = StageQuality.MEDIUM; 25 | 26 | //init scene 27 | scene = new Scene3D(); 28 | 29 | //init camera 30 | camera = new Camera3D(); 31 | camera.z = -1000; 32 | 33 | //init view 34 | view = new View3D(); 35 | view.scene = scene; 36 | view.camera = camera; 37 | 38 | //center view to stage 39 | view.x = stage.stageWidth/2; 40 | view.y = stage.stageHeight/2; 41 | 42 | //add view to the displaylist 43 | addChild(view); 44 | 45 | //init stats panel 46 | stats = new AwayStats(view); 47 | 48 | //add stats to the displaylist 49 | addChild(stats); 50 | 51 | //init debug textfield 52 | debugText = new TextField(); 53 | debugText.selectable = false; 54 | debugText.mouseEnabled = false; 55 | debugText.mouseWheelEnabled = false; 56 | debugText.defaultTextFormat = new TextFormat("Tahoma", 12, 0x000000); 57 | debugText.autoSize = "left"; 58 | debugText.x = 140; 59 | debugText.textColor = 0xFFFFFF; 60 | debugText.filters = [new GlowFilter(0x000000, 1, 4, 4, 2, 1)]; 61 | 62 | //add debug textfield to the displaylist 63 | addChild(debugText); 64 | 65 | //set default debug 66 | debug = true; 67 | 68 | //set default title 69 | title = "Away3DLite"; 70 | 71 | //add enterframe listener 72 | start(); 73 | 74 | //trigger onInit method 75 | onInit(); 76 | } 77 | 78 | private var stats:AwayStats; 79 | private var debugText:TextField; 80 | private var _title:String; 81 | private var _debug:Boolean; 82 | 83 | private function onAddedToStage(event:Event):void 84 | { 85 | removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 86 | init(); 87 | } 88 | 89 | private function onEnterFrame(event:Event):void 90 | { 91 | onPreRender(); 92 | 93 | view.render(); 94 | 95 | if (_debug) { 96 | debugText.text = _title + " Object3D(s) : " + view.totalObjects + ", Face(s) : " + view.totalFaces; 97 | onDebug(); 98 | } 99 | 100 | onPostRender(); 101 | } 102 | 103 | /** 104 | * Fired on instantiation of the template. 105 | */ 106 | protected function onInit():void 107 | { 108 | // override me 109 | } 110 | 111 | /** 112 | * Fired at the beginning of a render loop. 113 | */ 114 | protected function onPreRender():void 115 | { 116 | // override me 117 | } 118 | 119 | /** 120 | * Fired if debug is set to true. 121 | * 122 | * @see #debug 123 | */ 124 | protected function onDebug():void 125 | { 126 | // override me 127 | } 128 | 129 | /** 130 | * Fired at the end of a render loop. 131 | */ 132 | protected function onPostRender():void 133 | { 134 | // override me 135 | } 136 | 137 | /** 138 | * Defines the text appearing in the template title. 139 | */ 140 | public function get title():String 141 | { 142 | return _title; 143 | } 144 | 145 | public function set title(val:String):void 146 | { 147 | if (_title == val) 148 | return; 149 | 150 | _title = val; 151 | 152 | debugText.text = _title + ", Object3D(s) : " + view.totalObjects + ", Face(s) : " + view.totalFaces; 153 | } 154 | 155 | /** 156 | * Defines if the template is run in debug mode. 157 | */ 158 | public function get debug():Boolean 159 | { 160 | return _debug; 161 | } 162 | 163 | public function set debug(val:Boolean):void 164 | { 165 | if (_debug == val) 166 | return; 167 | 168 | _debug = val; 169 | 170 | debugText.visible = _debug; 171 | stats.visible = _debug; 172 | } 173 | 174 | /** 175 | * The scene object used in the template. 176 | */ 177 | public var scene:Scene3D; 178 | 179 | /** 180 | * The camera object used in the template. 181 | */ 182 | public var camera:Camera3D; 183 | 184 | /** 185 | * The view object used in the template. 186 | */ 187 | public var view:View3D; 188 | 189 | /** 190 | * Creates a new Template object. 191 | */ 192 | public function Template() 193 | { 194 | addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 195 | } 196 | 197 | /** 198 | * Starts the view rendering. 199 | */ 200 | public function start():void 201 | { 202 | addEventListener(Event.ENTER_FRAME, onEnterFrame); 203 | } 204 | 205 | /** 206 | * Stops the view rendering. 207 | */ 208 | public function stop():void 209 | { 210 | removeEventListener(Event.ENTER_FRAME, onEnterFrame); 211 | } 212 | } 213 | } -------------------------------------------------------------------------------- /src/away3dlite/primitives/Skybox6.as: -------------------------------------------------------------------------------- 1 | package away3dlite.primitives { import away3dlite.arcane; import away3dlite.core.base.*; import away3dlite.materials.*; use namespace arcane; /** * Creates a 3d Skybox primitive. */ public class Skybox6 extends AbstractPrimitive { private var _size:Number = 40000; private var _segments:int = 4; private var _pixelBorder:int = 1; /** * @inheritDoc */ protected override function buildPrimitive():void { super.buildPrimitive(); var i:int; var j:int; var udelta:Number = _pixelBorder/600; var vdelta:Number = _pixelBorder/400; if (material is BitmapMaterial) { var bMaterial:BitmapMaterial = material as BitmapMaterial; udelta = _pixelBorder/bMaterial.width; vdelta = _pixelBorder/bMaterial.height; } for (i = 0; i <= _segments; i++) { for (j = 0; j <= _segments; j++) { //create front/back _vertices.push(_size/2 - i*_size/_segments, _size/2 - j*_size/_segments, _size/2); _vertices.push(_size/2 - i*_size/_segments, _size/2 - j*_size/_segments, -_size/2); _uvtData.push(1/3 - udelta - i*(1 - 6*udelta)/(3*_segments), 1 - vdelta - j*(1 - 4*vdelta)/(2*_segments), 1); _uvtData.push(1/3 + udelta + i*(1 - 6*udelta)/(3*_segments), 1/2 - vdelta - j*(1 - 4*vdelta)/(2*_segments), 1); //create top/bottom _vertices.push(_size/2 - i*_size/_segments, -_size/2, _size/2 - j*_size/_segments); _vertices.push(_size/2 - i*_size/_segments, _size/2, _size/2 - j*_size/_segments); _uvtData.push(1/3 + udelta + j*(1 - 6*udelta)/(3*_segments), 1 - vdelta - i*(1 - 4*vdelta)/(2*_segments), 1); _uvtData.push(2/3 + udelta + j*(1 - 6*udelta)/(3*_segments), 1/2 + vdelta + i*(1 - 4*vdelta)/(2*_segments), 1); //create left/right _vertices.push(_size/2, _size/2 - i*_size/_segments, _size/2 - j*_size/_segments); _vertices.push(-_size/2, _size/2 - i*_size/_segments, _size/2 - j*_size/_segments); _uvtData.push(udelta + j*(1 - 6*udelta)/(3*_segments), 1/2 - vdelta - i*(1 - 4*vdelta)/(2*_segments), 1); _uvtData.push(1 - udelta - j*(1 - 6*udelta)/(3*_segments), 1/2 - vdelta - i*(1 - 4*vdelta)/(2*_segments), 1); } } for (i = 1; i <= _segments; i++) { for (j = 1; j <= _segments; j++) { var a:int = 6*((_segments + 1)*j + i); var b:int = 6*((_segments + 1)*j + i - 1); var c:int = 6*((_segments + 1)*(j - 1) + i - 1); var d:int = 6*((_segments + 1)*(j - 1) + i); _indices.push(a,b,c,d); _indices.push(b+1,a+1,d+1,c+1); _indices.push(a+2,b+2,c+2,d+2); _indices.push(b+3,a+3,d+3,c+3); _indices.push(a+4,b+4,c+4,d+4); _indices.push(b+5,a+5,d+5,c+5); _faceLengths.push(4,4,4,4,4,4); } } } /** * Defines the dimensions of the skybox. Defaults to 40000. */ public function get size():Number { return _size; } public function set size(val:Number):void { if (_size == val) return; _size = val; _primitiveDirty = true; } /** * Defines the number of segments that make up each face of the skybox. Defaults to 4. */ public function get segments():int { return _segments; } public function set segments(val:int):void { if (_segments == val) return; _segments = val; _primitiveDirty = true; } /** * Defines the texture mapping border in pixels used around each face of the skybox. Defaults to 1 */ public function get pixelBorder():int { return _pixelBorder; } public function set pixelBorder(val:int):void { if (_pixelBorder == val) return; _pixelBorder = val; _primitiveDirty = true; } /** * Creates a new Skybox6 object. * * @param material Defines the global material used on the faces in the skybox. * @param size Defines the size of the skybox. * @param segments Defines the number of segments that make up each face of the skybox. * @param pixelBorder Defines the texture mapping border in pixels used around each face of the skybox. */ public function Skybox6(material:Material = null, size:Number = 40000, segments:int = 4, pixelBorder:int = 1) { super(material); _size = size; _segments = segments; _pixelBorder = pixelBorder; type = "Skybox"; url = "primitive"; } /** * Duplicates the skybox6 properties to another Skybox6 object. * * @param object [optional] The new object instance into which all properties are copied. The default is Skybox6. * @return The new object instance with duplicated properties applied. */ public override function clone(object:Object3D = null):Object3D { var skybox6:Skybox6 = (object as Skybox6) || new Skybox6(); super.clone(skybox6); skybox6.size = _size; skybox6.segments = _segments; skybox6.pixelBorder = _pixelBorder; skybox6._primitiveDirty = false; return skybox6; } } } -------------------------------------------------------------------------------- /src/away3dlite/cameras/Camera3D.as: -------------------------------------------------------------------------------- 1 | package away3dlite.cameras 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.cameras.lenses.*; 5 | import away3dlite.containers.*; 6 | import away3dlite.core.base.*; 7 | 8 | import flash.geom.*; 9 | 10 | use namespace arcane; 11 | 12 | /** 13 | * Basic camera used to resolve a view. 14 | * 15 | * @see away3dlite.containers.View3D 16 | */ 17 | public class Camera3D extends Object3D 18 | { 19 | /** @private */ 20 | arcane var _view:View3D; 21 | arcane var _lens:AbstractLens; 22 | /** @private */ 23 | arcane var _invSceneMatrix3D:Matrix3D = new Matrix3D(); 24 | arcane var _projectionMatrix3D:Matrix3D; 25 | arcane var _screenMatrix3D:Matrix3D = new Matrix3D(); 26 | 27 | /** @private */ 28 | arcane function update():void 29 | { 30 | if (_lensDirty) { 31 | _lensDirty = false; 32 | _lens._update(); 33 | _projectionMatrix3D = _lens._projectionMatrix3D; 34 | } 35 | 36 | _invSceneMatrix3D.rawData = _sceneMatrix3D.rawData = transform.matrix3D.rawData; 37 | _invSceneMatrix3D.invert(); 38 | 39 | _screenMatrix3D.rawData = _invSceneMatrix3D.rawData; 40 | _screenMatrix3D.append(_projectionMatrix3D); 41 | } 42 | 43 | private var _focus:Number = 100; 44 | private var _zoom:Number = 10; 45 | private var _lensDirty:Boolean; 46 | 47 | protected const toRADIANS:Number = Math.PI/180; 48 | protected const toDEGREES:Number = 180/Math.PI; 49 | 50 | /** 51 | * Defines the distance from the focal point of the camera to the viewing plane. 52 | */ 53 | public function get focus():Number 54 | { 55 | return _focus; 56 | } 57 | public function set focus(val:Number):void 58 | { 59 | _focus = val; 60 | 61 | _lensDirty = true; 62 | } 63 | 64 | /** 65 | * Defines the overall scale value of the view. 66 | */ 67 | public function get zoom():Number 68 | { 69 | return _zoom; 70 | } 71 | 72 | public function set zoom(val:Number):void 73 | { 74 | _zoom = val; 75 | 76 | _lensDirty = true; 77 | } 78 | 79 | /** 80 | * Returns the 3d matrix representing the camera inverse scene transform for the view. 81 | */ 82 | public function get invSceneMatrix3D():Matrix3D 83 | { 84 | return _invSceneMatrix3D; 85 | } 86 | 87 | /** 88 | * Returns the 3d matrix representing the camera projection for the view. 89 | */ 90 | public function get projectionMatrix3D():Matrix3D 91 | { 92 | return _projectionMatrix3D; 93 | } 94 | 95 | /** 96 | * Returns the 3d matrix used in resolving screen space for the render loop. 97 | * 98 | * @see away3dlite.containers.View3D#render() 99 | */ 100 | public function get screenMatrix3D():Matrix3D 101 | { 102 | return _screenMatrix3D; 103 | } 104 | 105 | /** 106 | * Defines the lens used for calculating the projectionMatrix3D of the camera. 107 | */ 108 | public function get lens():AbstractLens 109 | { 110 | return _lens; 111 | } 112 | 113 | public function set lens(val:AbstractLens):void 114 | { 115 | if (_lens == val) 116 | return; 117 | 118 | if (_lens) 119 | _lens._camera = null; 120 | 121 | _lens = val; 122 | 123 | if (_lens) 124 | _lens._camera = this; 125 | else 126 | throw new Error("Camera cannot have lens set to null"); 127 | 128 | _lensDirty = true; 129 | } 130 | /** 131 | * Creates a new Camera3D object. 132 | * 133 | * @param focus Defines the distance from the focal point of the camera to the viewing plane. 134 | * @param zoom Defines the overall scale value of the view. 135 | * @param lens Defines the lens used for calculating the projectionMatrix3D of the camera. 136 | */ 137 | public function Camera3D(zoom:Number = 10, focus:Number = 100, lens:AbstractLens = null) 138 | { 139 | super(); 140 | 141 | this.lens = lens || new ZoomFocusLens(); 142 | this.zoom = zoom; 143 | this.focus = focus; 144 | 145 | //set default z position 146 | z = -1000; 147 | } 148 | 149 | /** 150 | * Rotates the Camera3D object around an axis by a defined degrees. 151 | * 152 | * @param degrees The degree of the rotation. 153 | * @param axis The axis or direction of rotation. The usual axes are the X_AXIS (Vector3D(1,0,0)), Y_AXIS (Vector3D(0,1,0)), and Z_AXIS (Vector3D(0,0,1)). 154 | * @param pivotPoint A point that determines the center of an object's rotation. The default pivot point for an object is its registration point. 155 | */ 156 | override public function rotate(degrees:Number, axis:Vector3D, pivotPoint:Vector3D = null):void 157 | { 158 | axis.normalize(); 159 | 160 | var _matrix3D:Matrix3D = transform.matrix3D; 161 | 162 | // keep current position 163 | var _position:Vector3D = _matrix3D.position.clone(); 164 | 165 | // need only rotation matrix 166 | _matrix3D.position = new Vector3D(); 167 | 168 | // rotate 169 | _matrix3D.appendRotation(degrees, _matrix3D.deltaTransformVector(axis), pivotPoint); 170 | 171 | // restore current position 172 | _matrix3D.position = _position; 173 | } 174 | 175 | /** 176 | * Returns a Vector3D object describing the resolved x and y position of the given 3d vertex position. 177 | * 178 | * @param vertex The vertex to be resolved. 179 | */ 180 | public function screen(vertex:Vector3D):Vector3D 181 | { 182 | update(); 183 | 184 | return Utils3D.projectVector(_screenMatrix3D, vertex); 185 | } 186 | } 187 | } -------------------------------------------------------------------------------- /src/away3dlite/cameras/HoverCamera3D.as: -------------------------------------------------------------------------------- 1 | package away3dlite.cameras 2 | { 3 | import away3dlite.cameras.lenses.*; 4 | import away3dlite.core.base.*; 5 | 6 | /** 7 | * Extended camera used to hover round a specified target object. 8 | * 9 | * @see away3dlite.containers.View3D 10 | */ 11 | public class HoverCamera3D extends TargetCamera3D 12 | { 13 | private var _currentPanAngle:Number = 0; 14 | private var _currentTiltAngle:Number = 0; 15 | 16 | /** 17 | * Rotation of the camera in degrees around the y axis. Defaults to 0. 18 | */ 19 | public var panAngle:Number = 0; 20 | 21 | /** 22 | * Elevation angle of the camera in degrees. Defaults to 90. 23 | */ 24 | public var tiltAngle:Number = 0; 25 | 26 | /** 27 | * Distance between the camera and the specified target. Defaults to 800. 28 | */ 29 | public var distance:Number = 800; 30 | 31 | /** 32 | * Minimum bounds for the tiltAngle. Defaults to -90. 33 | * 34 | * @see #tiltAngle 35 | */ 36 | public var minTiltAngle:Number = -90; 37 | 38 | /** 39 | * Maximum bounds for the tiltAngle. Defaults to 90. 40 | * 41 | * @see #tiltAngle 42 | */ 43 | public var maxTiltAngle:Number = 90; 44 | 45 | /** 46 | * Fractional step taken each time the hover() method is called. Defaults to 8. 47 | * 48 | * Affects the speed at which the tiltAngle and panAngle resolve to their targets. 49 | * 50 | * @see #tiltAngle 51 | * @see #panAngle 52 | */ 53 | public var steps:Number = 8; 54 | 55 | 56 | /** 57 | * Fractional difference in distance between the horizontal camera orientation and vertical camera orientation. Defaults to 2. 58 | * 59 | * @see #distance 60 | */ 61 | public var yfactor:Number = 2; 62 | 63 | /** 64 | * Defines whether the value of the pan angle wraps when over 360 degrees or under 0 degrees. Defaults to false. 65 | */ 66 | public var wrapPanAngle:Boolean = false; 67 | /** 68 | * Creates a new HoverCamera3D object. 69 | * 70 | * @param focus Defines the distance from the focal point of the camera to the viewing plane. 71 | * @param zoom Defines the overall scale value of the view. 72 | * @param target The 3d object targeted by the camera. 73 | */ 74 | public function HoverCamera3D(zoom:Number = 10, focus:Number = 100, target:Object3D = null, panAngle:Number = 0, tiltAngle:Number = 0, distance:Number = 800, lens:AbstractLens = null) 75 | { 76 | super(zoom, focus, target, lens); 77 | 78 | this.panAngle = panAngle; 79 | this.tiltAngle = tiltAngle; 80 | this.distance = distance; 81 | 82 | hover(); 83 | } 84 | 85 | /** 86 | * Updates the camera orientation. 87 | * Values are calculated using the defined tiltAngle, panAngle and steps variables. 88 | * 89 | * @param jumpTo Determines if step property is used. Defaults to false. 90 | * 91 | * @return True if the camera position was updated, otherwise false. 92 | * 93 | * @see #tiltAngle 94 | * @see #panAngle 95 | * @see #steps 96 | */ 97 | public function hover(jumpTo:Boolean = false):Boolean 98 | { 99 | if (tiltAngle != _currentTiltAngle || panAngle != _currentPanAngle) { 100 | 101 | tiltAngle = Math.max(minTiltAngle, Math.min(maxTiltAngle, tiltAngle)); 102 | 103 | if (wrapPanAngle) { 104 | if (panAngle < 0) 105 | panAngle = (panAngle % 360) + 360; 106 | else 107 | panAngle = panAngle % 360; 108 | 109 | if (panAngle - _currentPanAngle < -180) 110 | panAngle += 360; 111 | else if (panAngle - _currentPanAngle > 180) 112 | panAngle -= 360; 113 | } 114 | 115 | if (jumpTo) { 116 | _currentTiltAngle = tiltAngle; 117 | _currentPanAngle = panAngle; 118 | } else { 119 | _currentTiltAngle += (tiltAngle - _currentTiltAngle)/(steps + 1); 120 | _currentPanAngle += (panAngle - _currentPanAngle)/(steps + 1); 121 | } 122 | 123 | //snap coords if angle differences are close 124 | if ((Math.abs(tiltAngle - _currentTiltAngle) < 0.01) && (Math.abs(panAngle - _currentPanAngle) < 0.01)) { 125 | _currentTiltAngle = tiltAngle; 126 | _currentPanAngle = panAngle; 127 | } 128 | 129 | } 130 | 131 | var gx:Number = target.x + distance*Math.sin(_currentPanAngle*toRADIANS)*Math.cos(_currentTiltAngle*toRADIANS); 132 | var gz:Number = target.z + distance*Math.cos(_currentPanAngle*toRADIANS)*Math.cos(_currentTiltAngle*toRADIANS); 133 | var gy:Number = target.y - distance*Math.sin(_currentTiltAngle*toRADIANS)*yfactor; 134 | 135 | if ((x == gx) && (y == gy) && (z == gz)) 136 | return false; 137 | 138 | x = gx; 139 | y = gy; 140 | z = gz; 141 | 142 | return true; 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /src/away3dlite/primitives/Plane.as: -------------------------------------------------------------------------------- 1 | package away3dlite.primitives 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.base.*; 5 | import away3dlite.materials.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * Creates a 3d plane primitive. 11 | */ 12 | public class Plane extends AbstractPrimitive 13 | { 14 | private var _width:Number = 100; 15 | private var _height:Number = 100; 16 | private var _segmentsW:int = 1; 17 | private var _segmentsH:int = 1; 18 | private var _yUp:Boolean = true; 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | protected override function buildPrimitive():void 24 | { 25 | super.buildPrimitive(); 26 | 27 | var i:int; 28 | var j:int; 29 | 30 | for (j = 0; j <= _segmentsH; ++j) { 31 | for (i = 0; i <= _segmentsW; ++i) { 32 | _yUp? _vertices.push((i/_segmentsW - 0.5)*_width, 0, (j/_segmentsH - 0.5)*_height) : _vertices.push((i/_segmentsW - 0.5)*_width, (0.5 - j/_segmentsH)*_height, 0); 33 | _uvtData.push(i/_segmentsW, 1 - j/_segmentsH, 1); 34 | } 35 | } 36 | 37 | for (j = 1; j <= _segmentsH; ++j) { 38 | for (i = 1; i <= _segmentsW; ++i) { 39 | var a:int = (_segmentsW + 1)*j + i; 40 | var b:int = (_segmentsW + 1)*j + i - 1; 41 | var c:int = (_segmentsW + 1)*(j - 1) + i - 1; 42 | var d:int = (_segmentsW + 1)*(j - 1) + i; 43 | 44 | _indices.push(a,b,c,d); 45 | _faceLengths.push(4); 46 | } 47 | } 48 | } 49 | 50 | /** 51 | * Defines the width of the plane. Defaults to 100. 52 | */ 53 | public override function get width():Number 54 | { 55 | return _width; 56 | } 57 | 58 | public override function set width(val:Number):void 59 | { 60 | if (_width == val) 61 | return; 62 | 63 | _width = val; 64 | _primitiveDirty = true; 65 | } 66 | 67 | /** 68 | * Defines the height of the plane. Defaults to 100. 69 | */ 70 | public override function get height():Number 71 | { 72 | return _height; 73 | } 74 | 75 | public override function set height(val:Number):void 76 | { 77 | if (_height == val) 78 | return; 79 | 80 | _height = val; 81 | _primitiveDirty = true; 82 | } 83 | 84 | /** 85 | * Defines the number of horizontal segments that make up the plane. Defaults to 1. 86 | */ 87 | public function get segmentsW():int 88 | { 89 | return _segmentsW; 90 | } 91 | 92 | public function set segmentsW(val:int):void 93 | { 94 | if (_segmentsW == val) 95 | return; 96 | 97 | _segmentsW = val; 98 | _primitiveDirty = true; 99 | } 100 | 101 | /** 102 | * Defines the number of vertical segments that make up the plane. Defaults to 1. 103 | */ 104 | public function get segmentsH():int 105 | { 106 | return _segmentsH; 107 | } 108 | 109 | public function set segmentsH(val:int):void 110 | { 111 | if (_segmentsH == val) 112 | return; 113 | 114 | _segmentsH = val; 115 | _primitiveDirty = true; 116 | } 117 | 118 | /** 119 | * Defines whether the coordinates of the plane points use a yUp orientation (true) or a zUp orientation (false). Defaults to true. 120 | */ 121 | public function get yUp():Boolean 122 | { 123 | return _yUp; 124 | } 125 | 126 | public function set yUp(val:Boolean):void 127 | { 128 | if (_yUp == val) 129 | return; 130 | 131 | _yUp = val; 132 | _primitiveDirty = true; 133 | } 134 | 135 | /** 136 | * Creates a new Plane object. 137 | * 138 | * @param material Defines the global material used on the faces in the plane. 139 | * @param width Defines the width of the plane. 140 | * @param height Defines the height of the plane. 141 | * @param segmentsW Defines the number of horizontal segments that make up the plane. 142 | * @param segmentsH Defines the number of vertical segments that make up the plane. 143 | * @param yUp Defines whether the coordinates of the plane points use a yUp orientation (true) or a zUp orientation (false). 144 | */ 145 | public function Plane(material:Material = null, width:Number = 100, height:Number = 100, segmentsW:int = 1, segmentsH:int = 1, yUp:Boolean = true) 146 | { 147 | super(material); 148 | 149 | _width = width; 150 | _height = height; 151 | _segmentsW = segmentsW; 152 | _segmentsH = segmentsH; 153 | _yUp = yUp; 154 | 155 | type = "Plane"; 156 | url = "primitive"; 157 | } 158 | 159 | /** 160 | * Duplicates the plane properties to another Plane object. 161 | * 162 | * @param object [optional] The new object instance into which all properties are copied. The default is Plane. 163 | * @return The new object instance with duplicated properties applied. 164 | */ 165 | public override function clone(object:Object3D = null):Object3D 166 | { 167 | var plane:Plane = (object as Plane) || new Plane(); 168 | super.clone(plane); 169 | plane.width = _width; 170 | plane.height = _height; 171 | plane.segmentsW = _segmentsW; 172 | plane.segmentsH = _segmentsH; 173 | plane.yUp = _yUp; 174 | plane._primitiveDirty = false; 175 | 176 | return plane; 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/away3dlite/primitives/Torus.as: -------------------------------------------------------------------------------- 1 | package away3dlite.primitives 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.base.*; 5 | import away3dlite.materials.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * Creates a 3d torus primitive. 11 | */ 12 | public class Torus extends AbstractPrimitive 13 | { 14 | private var _radius:Number = 100; 15 | private var _tube:Number = 40; 16 | private var _segmentsR:int = 8; 17 | private var _segmentsT:int = 6; 18 | private var _yUp:Boolean = true; 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | protected override function buildPrimitive():void 24 | { 25 | super.buildPrimitive(); 26 | 27 | var i:int; 28 | var j:int; 29 | 30 | for (j = 0; j <= _segmentsR; ++j) { 31 | for (i = 0; i <= _segmentsT; ++i) { 32 | var u:Number = i / _segmentsT * 2 * Math.PI; 33 | var v:Number = j / _segmentsR * 2 * Math.PI; 34 | var x:Number = (_radius + _tube*Math.cos(v))*Math.cos(u); 35 | var y:Number = (_radius + _tube*Math.cos(v))*Math.sin(u); 36 | var z:Number = _tube*Math.sin(v); 37 | 38 | _yUp? _vertices.push(x, -z, y) : _vertices.push(x, y, z); 39 | 40 | _uvtData.push(i/_segmentsT, 1 - j/_segmentsR, 1); 41 | } 42 | } 43 | 44 | 45 | for (j = 1; j <= _segmentsR; ++j) { 46 | for (i = 1; i <= _segmentsT; ++i) { 47 | var a:int = (_segmentsT + 1)*j + i; 48 | var b:int = (_segmentsT + 1)*j + i - 1; 49 | var c:int = (_segmentsT + 1)*(j - 1) + i - 1; 50 | var d:int = (_segmentsT + 1)*(j - 1) + i; 51 | 52 | _indices.push(a,b,c,d); 53 | _faceLengths.push(4); 54 | } 55 | } 56 | } 57 | 58 | /** 59 | * Defines the overall radius of the torus. Defaults to 100. 60 | */ 61 | public function get radius():Number 62 | { 63 | return _radius; 64 | } 65 | 66 | public function set radius(val:Number):void 67 | { 68 | if (_radius == val) 69 | return; 70 | 71 | _radius = val; 72 | _primitiveDirty = true; 73 | } 74 | 75 | /** 76 | * Defines the tube radius of the torus. Defaults to 40. 77 | */ 78 | public function get tube():Number 79 | { 80 | return _tube; 81 | } 82 | 83 | public function set tube(val:Number):void 84 | { 85 | if (_tube == val) 86 | return; 87 | 88 | _tube = val; 89 | _primitiveDirty = true; 90 | } 91 | 92 | /** 93 | * Defines the number of radial segments that make up the torus. Defaults to 8. 94 | */ 95 | public function get segmentsR():Number 96 | { 97 | return _segmentsR; 98 | } 99 | 100 | public function set segmentsR(val:Number):void 101 | { 102 | if (_segmentsR == val) 103 | return; 104 | 105 | _segmentsR = val; 106 | _primitiveDirty = true; 107 | } 108 | 109 | /** 110 | * Defines the number of tubular segments that make up the torus. Defaults to 6. 111 | */ 112 | public function get segmentsT():Number 113 | { 114 | return _segmentsT; 115 | } 116 | 117 | public function set segmentsT(val:Number):void 118 | { 119 | if (_segmentsT == val) 120 | return; 121 | 122 | _segmentsT = val; 123 | _primitiveDirty = true; 124 | } 125 | 126 | /** 127 | * Defines whether the coordinates of the torus points use a yUp orientation (true) or a zUp orientation (false). Defaults to true. 128 | */ 129 | public function get yUp():Boolean 130 | { 131 | return _yUp; 132 | } 133 | 134 | public function set yUp(val:Boolean):void 135 | { 136 | if (_yUp == val) 137 | return; 138 | 139 | _yUp = val; 140 | _primitiveDirty = true; 141 | } 142 | 143 | /** 144 | * Creates a new Torus object. 145 | * 146 | * @param material Defines the global material used on the faces in the torus. 147 | * @param radius Defines the overall radius of the torus. 148 | * @param tube Defines the tube radius of the torus. 149 | * @param segmentsR Defines the number of radial segments that make up the torus. 150 | * @param segmentsT Defines the number of tubular segments that make up the torus. 151 | * @param yUp Defines whether the coordinates of the torus points use a yUp orientation (true) or a zUp orientation (false). 152 | */ 153 | public function Torus(material:Material = null, radius:Number = 100, tube:Number = 40, segmentsR:int = 8, segmentsT:int = 6, yUp:Boolean = true) 154 | { 155 | super(material); 156 | 157 | _radius = radius; 158 | _tube = tube; 159 | _segmentsR = segmentsR; 160 | _segmentsT = segmentsT; 161 | _yUp = yUp; 162 | 163 | type = "Torus"; 164 | url = "primitive"; 165 | } 166 | 167 | /** 168 | * Duplicates the torus properties to another Torus object. 169 | * 170 | * @param object [optional] The new object instance into which all properties are copied. The default is Torus. 171 | * @return The new object instance with duplicated properties applied. 172 | */ 173 | public override function clone(object:Object3D = null):Object3D 174 | { 175 | var torus:Torus = (object as Torus) || new Torus(); 176 | super.clone(torus); 177 | torus.radius = _radius; 178 | torus.tube = _tube; 179 | torus.segmentsR = _segmentsR; 180 | torus.segmentsT = _segmentsT; 181 | torus.yUp = _yUp; 182 | torus._primitiveDirty = false; 183 | 184 | return torus; 185 | } 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/away3dlite/sprites/Sprite3D.as: -------------------------------------------------------------------------------- 1 | package away3dlite.sprites 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.materials.*; 5 | 6 | import flash.geom.*; 7 | 8 | use namespace arcane; 9 | 10 | /** 11 | * Single billboard object (one that always faces the camera). 12 | * Draws 2d objects inline with z-sorted triangles in a scene. 13 | */ 14 | public class Sprite3D 15 | { 16 | /** @private */ 17 | arcane var index:int; 18 | /** @private */ 19 | arcane var indices:Vector. = new Vector.(); 20 | /** @private */ 21 | arcane var uvtData:Vector. = new Vector.(); 22 | 23 | private var _scale:Number = 1; 24 | private var _width:Number; 25 | private var _height:Number; 26 | private var _vertices:Vector. = new Vector.(); 27 | private var _verticesDirty:Boolean; 28 | private var _material:Material; 29 | private var _position:Vector3D = new Vector3D(); 30 | 31 | protected function updateVertices():void 32 | { 33 | _verticesDirty = false; 34 | 35 | _vertices.fixed = false; 36 | _vertices.length = 0; 37 | _vertices.push(-_width*_scale/2, -_height*_scale/2, 0); 38 | _vertices.push(-_width*_scale/2, _height*_scale/2, 0); 39 | _vertices.push(_width*_scale/2, _height*_scale/2, 0); 40 | _vertices.push(_width*_scale/2, -_height*_scale/2, 0); 41 | _vertices.fixed = true; 42 | } 43 | 44 | /** 45 | * Defines the x position of the Sprite3D object. Defaults to 0. 46 | */ 47 | public var x:Number = 0; 48 | 49 | /** 50 | * Defines the y position of the Sprite3D object. Defaults to 0. 51 | */ 52 | public var y:Number = 0; 53 | 54 | /** 55 | * Defines the z position of the Sprite3D object. Defaults to 0. 56 | */ 57 | public var z:Number = 0; 58 | 59 | /** 60 | * Defines the way the sprite aligns its plane to face the viewer. Allowed values are "viewplane" or "viewpoint". Defaults to "viewplane". 61 | * 62 | * @see away3dlite.sprites.AlignmentType 63 | */ 64 | public var alignmentType:String; 65 | 66 | /** 67 | * Defines the overall scale of the Sprite3D object. Defaults to 1. 68 | */ 69 | public function get scale():Number 70 | { 71 | return _scale; 72 | } 73 | 74 | public function set scale(val:Number):void 75 | { 76 | if (_scale == val) 77 | return; 78 | 79 | _scale = val; 80 | _verticesDirty = true; 81 | } 82 | 83 | /** 84 | * Defines the width of the Sprite3D object. Defaults to the material width if BitmapMaterial, otherwise 100. 85 | */ 86 | public function get width():Number 87 | { 88 | if (isNaN(_width)) 89 | return 100; 90 | 91 | return _width; 92 | } 93 | 94 | public function set width(val:Number):void 95 | { 96 | if (_width == val) 97 | return; 98 | 99 | _width = val; 100 | _verticesDirty = true; 101 | } 102 | 103 | /** 104 | * Defines the height of the Sprite3D object. Defaults to the material height if BitmapMaterial, otherwise 100. 105 | */ 106 | public function get height():Number 107 | { 108 | if (isNaN(_height)) 109 | return 100; 110 | 111 | return _height; 112 | } 113 | 114 | public function set height(val:Number):void 115 | { 116 | if (_height == val) 117 | return; 118 | 119 | _height = val; 120 | _verticesDirty = true; 121 | } 122 | 123 | /** 124 | * @inheritDoc 125 | */ 126 | public function get vertices():Vector. 127 | { 128 | if (_verticesDirty) 129 | updateVertices(); 130 | 131 | return _vertices; 132 | } 133 | 134 | /** 135 | * Determines the material used on the sprite. 136 | */ 137 | public function get material():Material 138 | { 139 | return _material; 140 | } 141 | public function set material(val:Material):void 142 | { 143 | val = val || new WireColorMaterial(); 144 | 145 | if (_material == val) 146 | return; 147 | 148 | _material = val; 149 | 150 | if (_material is BitmapMaterial) { 151 | var bitmapMaterial:BitmapMaterial = _material as BitmapMaterial; 152 | 153 | if (isNaN(_width)) 154 | width = bitmapMaterial.width; 155 | if (isNaN(_height)) 156 | height = bitmapMaterial.height; 157 | } 158 | } 159 | 160 | /** 161 | * Returns a 3d vector representing the local position of the 3d sprite. 162 | */ 163 | public function get position():Vector3D 164 | { 165 | _position.x = x; 166 | _position.y = y; 167 | _position.z = z; 168 | 169 | return _position; 170 | } 171 | 172 | /** 173 | * Creates a new Sprite3D object. 174 | * 175 | * @param material Determines the material used on the faces in the Sprite3D object. 176 | */ 177 | public function Sprite3D(material:Material = null, scale:Number = 1) 178 | { 179 | super(); 180 | 181 | this.material = material; 182 | this.scale = scale; 183 | this.alignmentType = AlignmentType.VIEWPLANE; 184 | 185 | //create indices for sprite 186 | indices.push(0, 1, 2, 3); 187 | 188 | //create uvtData for sprite 189 | uvtData.push(0, 0, 0); 190 | uvtData.push(0, 1, 0); 191 | uvtData.push(1, 1, 0); 192 | uvtData.push(1, 0, 0); 193 | 194 | //create faces 195 | updateVertices(); 196 | } 197 | 198 | 199 | /** 200 | * Duplicates the sprite3d properties to another Sprite3D object. 201 | * 202 | * @param object [optional] The new object instance into which all properties are copied. The default is Sprite3D. 203 | * @return The new object instance with duplicated properties applied. 204 | */ 205 | public function clone(object:Sprite3D = null):Sprite3D 206 | { 207 | var sprite3D:Sprite3D = (object as Sprite3D) || new Sprite3D(); 208 | sprite3D.x = x; 209 | sprite3D.y = y; 210 | sprite3D.z = z; 211 | sprite3D.scale = scale; 212 | sprite3D.width = _width; 213 | sprite3D.height = _height; 214 | sprite3D.material = material; 215 | 216 | return sprite3D; 217 | } 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /src/away3dlite/core/utils/Cast.as: -------------------------------------------------------------------------------- 1 | package away3dlite.core.utils { 2 | 3 | import away3dlite.materials.*; 4 | 5 | import flash.display.*; 6 | import flash.geom.*; 7 | import flash.utils.*; 8 | 9 | 10 | /** 11 | * Helper class for casting assets to usable objects 12 | */ 13 | public class Cast 14 | { 15 | private static var hexchars:String = "0123456789abcdefABCDEF"; 16 | private static var notclasses:Dictionary = new Dictionary(); 17 | private static var classes:Dictionary = new Dictionary(); 18 | 19 | private static function tryclass(name:String):Object 20 | { 21 | if (notclasses[name]) 22 | return name; 23 | 24 | var result:Class = classes[name]; 25 | 26 | if (result != null) 27 | return result; 28 | 29 | try 30 | { 31 | result = getDefinitionByName(name) as Class; 32 | classes[name] = result; 33 | return result; 34 | } 35 | catch (error:ReferenceError) {} 36 | 37 | notclasses[name] = true; 38 | return name; 39 | } 40 | 41 | private static function hexstring(string:String):Boolean 42 | { 43 | var _length:int = string.length; 44 | for (var i:int = 0; i < _length; ++i) 45 | if (hexchars.indexOf(string.charAt(i)) == -1) 46 | return false; 47 | 48 | return true; 49 | } 50 | 51 | /** 52 | * Casts the given data value as a string. 53 | */ 54 | public static function string(data:*):String 55 | { 56 | if (data is Class) 57 | data = new data; 58 | 59 | if (data is String) 60 | return data; 61 | 62 | return String(data); 63 | } 64 | 65 | /** 66 | * Casts the given data value as a bytearray. 67 | */ 68 | public static function bytearray(data:*):ByteArray 69 | { 70 | //throw new Error(typeof(data)); 71 | 72 | if (data is Class) 73 | data = new data; 74 | 75 | if (data is ByteArray) 76 | return data; 77 | 78 | return ByteArray(data); 79 | } 80 | 81 | /** 82 | * Casts the given data value as an xml object. 83 | */ 84 | public static function xml(data:*):XML 85 | { 86 | if (data is Class) 87 | data = new data; 88 | 89 | if (data is XML) 90 | return data; 91 | 92 | return XML(data); 93 | } 94 | 95 | /** 96 | * Casts the given data value as a color. 97 | */ 98 | public static function color(data:*):uint 99 | { 100 | if (data is uint) 101 | return data as uint; 102 | 103 | if (data is int) 104 | return data as uint; 105 | 106 | if (data is String) 107 | { 108 | if (data == "random") 109 | return uint(Math.random()*0x1000000); 110 | 111 | if (((data as String).length == 6) && hexstring(data)) 112 | return parseInt("0x"+data); 113 | } 114 | 115 | return 0xFFFFFF; 116 | } 117 | 118 | /** 119 | * Casts the given data value as a bitmapdata object. 120 | */ 121 | public static function bitmap(data:*):BitmapData 122 | { 123 | if (data == null) 124 | return null; 125 | 126 | if (data is String) 127 | data = tryclass(data); 128 | 129 | if (data is Class) 130 | { 131 | try 132 | { 133 | data = new data; 134 | } 135 | catch (bitmaperror:ArgumentError) 136 | { 137 | data = new data(0,0); 138 | } 139 | } 140 | 141 | if (data is BitmapData) 142 | return data; 143 | 144 | if (data is Bitmap) 145 | if ((data as Bitmap).hasOwnProperty("bitmapData")) // if (data is BitmapAsset) 146 | return (data as Bitmap).bitmapData; 147 | 148 | if (data is DisplayObject) 149 | { 150 | var ds:DisplayObject = data as DisplayObject; 151 | var bmd:BitmapData = new BitmapData(ds.width, ds.height, true, 0x00FFFFFF); 152 | var mat:Matrix = ds.transform.matrix.clone(); 153 | mat.tx = 0; 154 | mat.ty = 0; 155 | bmd.draw(ds, mat, ds.transform.colorTransform, ds.blendMode, bmd.rect, true); 156 | return bmd; 157 | } 158 | 159 | throw new Error("Can't cast to bitmap: "+data); 160 | } 161 | 162 | /** 163 | * Casts the given data value as a material object. 164 | */ 165 | public static function material(data:*):Material 166 | { 167 | if (data == null) 168 | return null; 169 | 170 | if (data is String) 171 | data = tryclass(data); 172 | 173 | if (data is Class) 174 | { 175 | try 176 | { 177 | data = new data; 178 | } 179 | catch (materialerror:ArgumentError) 180 | { 181 | data = new data(0,0); 182 | } 183 | } 184 | 185 | if (data is Material) 186 | return data; 187 | 188 | if (data is int) 189 | return new ColorMaterial(data); 190 | 191 | //if (data is MovieClip) 192 | // return new MovieMaterial(data); 193 | 194 | if (data is String) 195 | { 196 | if (data == "") 197 | return null; 198 | } 199 | 200 | try 201 | { 202 | var bmd:BitmapData = Cast.bitmap(data); 203 | return new BitmapMaterial(bmd); 204 | } 205 | catch (error:Error) {} 206 | 207 | throw new Error("Can't cast to material: "+data); 208 | } 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /src/away3dlite/primitives/Sphere.as: -------------------------------------------------------------------------------- 1 | package away3dlite.primitives 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.base.*; 5 | import away3dlite.materials.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * Creates a 3d sphere primitive. 11 | */ 12 | public class Sphere extends AbstractPrimitive 13 | { 14 | private var _radius:Number = 100; 15 | private var _arcLength:Number = 1; 16 | private var _segmentsW:int = 8; 17 | private var _segmentsH:int = 6; 18 | private var _yUp:Boolean = true; 19 | 20 | /** 21 | * @inheritDoc 22 | */ 23 | protected override function buildPrimitive():void 24 | { 25 | super.buildPrimitive(); 26 | 27 | var i:int; 28 | var j:int; 29 | var minJ:int = int(_segmentsH*(1-_arcLength)); 30 | 31 | for (j = minJ; j <= _segmentsH; ++j) { 32 | var horangle:Number = Math.PI*j/_segmentsH; 33 | var z:Number = -_radius*Math.cos(horangle); 34 | var ringradius:Number = _radius*Math.sin(horangle); 35 | 36 | for (i = 0; i <= _segmentsW; ++i) { 37 | var verangle:Number = 2*Math.PI*i/_segmentsW; 38 | var x:Number = ringradius*Math.cos(verangle); 39 | var y:Number = ringradius*Math.sin(verangle); 40 | 41 | _yUp? _vertices.push(x, -z, y) : _vertices.push(x, y, z); 42 | 43 | _uvtData.push(i/_segmentsW, 1 - (j - minJ)/(_segmentsH - minJ), 1); 44 | } 45 | } 46 | 47 | for (j = 1; j <= _segmentsH - minJ; ++j) { 48 | for (i = 1; i <= _segmentsW; ++i) { 49 | var a:int = (_segmentsW + 1)*j + i; 50 | var b:int = (_segmentsW + 1)*j + i - 1; 51 | var c:int = (_segmentsW + 1)*(j - 1) + i - 1; 52 | var d:int = (_segmentsW + 1)*(j - 1) + i; 53 | 54 | if (j == _segmentsH - minJ) { 55 | _indices.push(a,c,d); 56 | _faceLengths.push(3); 57 | } else if (j == 1 - minJ) { 58 | _indices.push(a,b,c); 59 | _faceLengths.push(3); 60 | } else { 61 | _indices.push(a,b,c,d); 62 | _faceLengths.push(4); 63 | } 64 | 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * Defines the fractional arc of the sphere rendered from the top. 71 | */ 72 | public function get arcLength():Number 73 | { 74 | return _arcLength; 75 | } 76 | 77 | public function set arcLength(val:Number):void 78 | { 79 | if (_arcLength == val) 80 | return; 81 | 82 | _arcLength = val; 83 | _primitiveDirty = true; 84 | } 85 | 86 | /** 87 | * Defines the radius of the sphere. Defaults to 100. 88 | */ 89 | public function get radius():Number 90 | { 91 | return _radius; 92 | } 93 | 94 | public function set radius(val:Number):void 95 | { 96 | if (_radius == val) 97 | return; 98 | 99 | _radius = val; 100 | _primitiveDirty = true; 101 | } 102 | 103 | /** 104 | * Defines the number of horizontal segments that make up the sphere. Defaults to 8. 105 | */ 106 | public function get segmentsW():Number 107 | { 108 | return _segmentsW; 109 | } 110 | 111 | public function set segmentsW(val:Number):void 112 | { 113 | if (_segmentsW == val) 114 | return; 115 | 116 | _segmentsW = val; 117 | _primitiveDirty = true; 118 | } 119 | 120 | /** 121 | * Defines the number of vertical segments that make up the sphere. Defaults to 1. 122 | */ 123 | public function get segmentsH():Number 124 | { 125 | return _segmentsH; 126 | } 127 | 128 | public function set segmentsH(val:Number):void 129 | { 130 | if (_segmentsH == val) 131 | return; 132 | 133 | _segmentsH = val; 134 | _primitiveDirty = true; 135 | } 136 | 137 | /** 138 | * Defines whether the coordinates of the sphere points use a yUp orientation (true) or a zUp orientation (false). Defaults to true. 139 | */ 140 | public function get yUp():Boolean 141 | { 142 | return _yUp; 143 | } 144 | 145 | public function set yUp(val:Boolean):void 146 | { 147 | if (_yUp == val) 148 | return; 149 | 150 | _yUp = val; 151 | _primitiveDirty = true; 152 | } 153 | 154 | /** 155 | * Creates a new Sphere object. 156 | * 157 | * @param material Defines the global material used on the faces in the sphere. 158 | * @param radius Defines the radius of the sphere base. 159 | * @param segmentsW Defines the number of horizontal segments that make up the sphere. 160 | * @param segmentsH Defines the number of vertical segments that make up the sphere. 161 | * @param yUp Defines whether the coordinates of the sphere points use a yUp orientation (true) or a zUp orientation (false). 162 | */ 163 | public function Sphere(material:Material = null, radius:Number = 100, segmentsW:int = 8, segmentsH:int = 6, yUp:Boolean = true) 164 | { 165 | super(material); 166 | 167 | _radius = radius; 168 | _segmentsW = segmentsW; 169 | _segmentsH = segmentsH; 170 | _yUp = yUp; 171 | 172 | type = "Sphere"; 173 | url = "primitive"; 174 | } 175 | 176 | /** 177 | * Duplicates the sphere properties to another Sphere object. 178 | * 179 | * @param object [optional] The new object instance into which all properties are copied. The default is Sphere. 180 | * @return The new object instance with duplicated properties applied. 181 | */ 182 | public override function clone(object:Object3D = null):Object3D 183 | { 184 | var sphere:Sphere = (object as Sphere) || new Sphere(); 185 | super.clone(sphere); 186 | sphere.radius = _radius; 187 | sphere.arcLength = _arcLength; 188 | sphere.segmentsW = _segmentsW; 189 | sphere.segmentsH = _segmentsH; 190 | sphere.yUp = _yUp; 191 | sphere._primitiveDirty = false; 192 | 193 | return sphere; 194 | } 195 | } 196 | } -------------------------------------------------------------------------------- /src/away3dlite/materials/Dot3BitmapMaterial.as: -------------------------------------------------------------------------------- 1 | package away3dlite.materials { import away3dlite.arcane; import away3dlite.cameras.*; import away3dlite.core.base.*; import away3dlite.lights.*; import flash.display.*; import flash.filters.*; import flash.geom.*; use namespace arcane; /** * Bitmap material with DOT3 shading. */ public class Dot3BitmapMaterial extends BitmapMaterial { private var _shaderJob:ShaderJob; private var _shaderBlendMode:String = BlendMode.HARDLIGHT; private var _lightMap:BitmapData; private var _bitmap:BitmapData; private var _shininess:Number = 20; private var _specular:Number = 0.7; private var _normalMap:BitmapData; private var _normalVector:Vector.; private var _normalShader:Shader; private var _normalFilter:ShaderFilter; private var _light:AbstractLight3D; private var _directionalLight:DirectionalLight3D; private var _pointLight:PointLight3D; private var _zeroPoint:Point = new Point(); private var _positionMapDirty:Boolean; private var _positionVector:Vector.; [Embed(source="../../../pbj/normalMapping.pbj",mimeType="application/octet-stream")] private var NormalShader:Class; arcane override function updateMaterial(source:Mesh, camera:Camera3D):void { _lightMap.fillRect(_lightMap.rect, 0); for each (_light in source.scene.sceneLights) { if ((_directionalLight = _light as DirectionalLight3D)) { var _red:Number = _directionalLight._red*_directionalLight.diffuse; var _green:Number = _directionalLight._green*_directionalLight.diffuse; var _blue:Number = _directionalLight._blue*_directionalLight.diffuse; var diffuseTransform:Matrix3D = _directionalLight.diffuseTransform.clone(); diffuseTransform.prepend(source.sceneMatrix3D); var diffuseRawData:Vector. = diffuseTransform.rawData; var _szx:Number = diffuseRawData[2]; var _szy:Number = diffuseRawData[6]; var _szz:Number = -diffuseRawData[10]; var mod:Number = Math.sqrt(_szx*_szx + _szy*_szy + _szz*_szz); _szx /= mod; _szy /= mod; _szz /= mod; _normalShader.data.diffuseMatrixR.value = [_red*_szx, _green*_szx, _blue*_szx, 0]; _normalShader.data.diffuseMatrixG.value = [_red*_szy, _green*_szy, _blue*_szy, 0]; _normalShader.data.diffuseMatrixB.value = [_red*_szz, _green*_szz, _blue*_szz, 0]; _normalShader.data.diffuseMatrixO.value = [-_red*(_szx + _szy + _szz)/2, -_green*(_szx + _szy + _szz)/2, -_blue*(_szx + _szy + _szz)/2, 1]; _normalShader.data.ambientMatrixO.value = [_directionalLight._red*_directionalLight.ambient, _directionalLight._green*_directionalLight.ambient, _directionalLight._blue*_directionalLight.ambient, 1]; _red = (_directionalLight._red + _shininess)*_specular*2; _green = (_directionalLight._green + _shininess)*_specular*2; _blue = (_directionalLight._blue + _shininess)*_specular*2; var specularTransform:Matrix3D = _directionalLight.specularTransform.clone(); specularTransform.prepend(source.sceneMatrix3D); var specularRawData:Vector. = specularTransform.rawData; _szx = specularRawData[2]; _szy = specularRawData[6]; _szz = -specularRawData[10]; _normalShader.data.specularMatrixR.value = [_red*_szx, _green*_szx, _blue*_szx, 0]; _normalShader.data.specularMatrixG.value = [_red*_szy, _green*_szy, _blue*_szy, 0]; _normalShader.data.specularMatrixB.value = [_red*_szz, _green*_szz, _blue*_szz, 0]; _normalShader.data.specularMatrixO.value = [-_red*(_szx + _szy + _szz)/2 -shininess*specular, -_green*(_szx + _szy + _szz)/2 -shininess*specular, -_blue*(_szx + _szy + _szz)/2 -shininess*specular, 1]; _normalShader.data.lightMap.input = _lightMap; _shaderJob = new ShaderJob(_normalShader, _lightMap); _shaderJob.start(true); } else if ((_pointLight = _light as PointLight3D)) { if (_positionMapDirty) { _positionMapDirty = false; } } } _graphicsBitmapFill.bitmapData = _bitmap.clone(); _graphicsBitmapFill.bitmapData.draw(_lightMap, null, null, _shaderBlendMode); //_graphicsBitmapFill.bitmapData.applyFilter(_bitmap, bitmap.rect, _zeroPoint, _normalFilter); super.updateMaterial(source, camera); } /** * The exponential dropoff value used for specular highlights. */ public function get shininess():Number { return _shininess; } public function set shininess(val:Number):void { _shininess = val; } /** * Coefficient for specular light level. */ public function get specular():Number { return _specular; } public function set specular(val:Number):void { _specular = val; } /** * Returns the bitmapData object being used as the material normal map. */ public function get normalMap():BitmapData { return _normalMap; } /** * Creates a new Dot3BitmapMaterial object. * * @param bitmap The bitmapData object to be used as the material's texture. * @param normalMap The bitmapData object to be used as the material's DOT3 map. * @param init [optional] An initialisation object for specifying default instance properties. */ public function Dot3BitmapMaterial(bitmap:BitmapData, normalMap:BitmapData) { super(bitmap); _lightMap = bitmap.clone(); _bitmap = bitmap; _normalMap = normalMap; _normalVector = new Vector.(_normalMap.width*_normalMap.height*4); var w:int = _normalMap.width; var h:int = _normalMap.height; var i:int = h; var j:int; var pixel:int; var pixelValue:int; var rValue:Number; var gValue:Number; var bValue:Number; var mod:Number; //normalise map while (i--) { j = w; while (j--) { //get values pixelValue = _normalMap.getPixel32(j, i); rValue = ((pixelValue & 0x00FF0000) >> 16)- 127; gValue = ((pixelValue & 0x0000FF00) >> 8) - 127; bValue = ((pixelValue & 0x000000FF)) - 127; //calculate modulus mod = Math.sqrt(rValue*rValue + gValue*gValue + bValue*bValue)*2; //set normalised values pixel = i*w*4 + j*4; _normalVector[pixel] = rValue/mod + 0.5; _normalVector[pixel + 1] = gValue/mod + 0.5; _normalVector[pixel + 2] = bValue/mod + 0.5; _normalVector[pixel + 3] = 1; } } _normalShader = new Shader(new NormalShader()); _normalShader.data.normalMap.width = w; _normalShader.data.normalMap.height = h; _normalShader.data.normalMap.input = _normalVector; _normalFilter = new ShaderFilter(_normalShader); } } } -------------------------------------------------------------------------------- /src/away3dlite/loaders/utils/TextureLoadQueue.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders.utils 2 | { 3 | import flash.events.Event; 4 | import flash.events.EventDispatcher; 5 | import flash.events.HTTPStatusEvent; 6 | import flash.events.IOErrorEvent; 7 | import flash.events.ProgressEvent; 8 | import flash.events.SecurityErrorEvent; 9 | import flash.net.URLRequest; 10 | 11 | 12 | 13 | [Event(name="complete", type="flash.events.Event")] 14 | [Event(name="httpStatus", type="flash.events.HTTPStatusEvent")] 15 | [Event(name="ioError", type="flash.events.IOErrorEvent")] 16 | [Event(name="progress", type="flash.events.ProgressEvent")] 17 | [Event(name="securityError", type="flash.events.SecurityErrorEvent")] 18 | 19 | /** 20 | * Creates a queue of textures that load sequentially 21 | */ 22 | public class TextureLoadQueue extends EventDispatcher 23 | { 24 | private var _queue:Array; 25 | private var _currentItemIndex:int; 26 | 27 | private function redispatchEvent(e:Event):void 28 | { 29 | dispatchEvent(e); 30 | } 31 | 32 | private function onItemComplete(e:Event):void 33 | { 34 | cleanUpOldItem(currentLoader); 35 | _currentItemIndex++; 36 | loadNext(); 37 | } 38 | 39 | private function loadNext():void 40 | { 41 | if(_currentItemIndex >= numItems){ 42 | dispatchEvent(new Event(Event.COMPLETE)); 43 | }else{ 44 | var evt:ProgressEvent = new ProgressEvent(ProgressEvent.PROGRESS); 45 | evt.bytesTotal = 100; 46 | evt.bytesLoaded = percentLoaded; 47 | dispatchEvent(evt); 48 | if(currentLoader.contentLoaderInfo.bytesLoaded > 0 && currentLoader.contentLoaderInfo.bytesLoaded == currentLoader.contentLoaderInfo.bytesTotal){ 49 | 50 | }else{ 51 | 52 | // make it lowest priority so we handle it after the loader handles the event itself. That means that when we 53 | // re-dispatch the event, the loaders have already processed their data and are ready for use 54 | currentLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onItemComplete, false, int.MIN_VALUE, true); 55 | 56 | currentLoader.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, redispatchEvent, false, 0, true); 57 | currentLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, redispatchEvent, false, 0, true); 58 | currentLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, redispatchEvent, false, 0, true); 59 | currentLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, redispatchEvent, false, 0, true); 60 | currentLoader.load(currentURLRequest); 61 | } 62 | } 63 | } 64 | 65 | private function calcProgress():Number 66 | { 67 | var baseAmount:Number = currentItemIndex / numItems; 68 | var currentItemFactor:Number = calcCurrentLoaderAmountLoaded() / numItems; 69 | return baseAmount = currentItemFactor; 70 | } 71 | 72 | private function calcCurrentLoaderAmountLoaded():Number 73 | { 74 | if(currentLoader.contentLoaderInfo.bytesLoaded > 0){ 75 | return currentLoader.contentLoaderInfo.bytesLoaded / currentLoader.contentLoaderInfo.bytesTotal; 76 | }else{ 77 | return 0; 78 | } 79 | } 80 | 81 | private function cleanUpOldItem(item:TextureLoader):void 82 | { 83 | item;//TODO : FDT Warning 84 | currentLoader.removeEventListener(Event.COMPLETE, onItemComplete, false); 85 | currentLoader.removeEventListener(HTTPStatusEvent.HTTP_STATUS, redispatchEvent, false); 86 | currentLoader.removeEventListener(IOErrorEvent.IO_ERROR, redispatchEvent, false); 87 | currentLoader.removeEventListener(ProgressEvent.PROGRESS, redispatchEvent, false); 88 | currentLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, redispatchEvent, false); 89 | } 90 | 91 | /** 92 | * Returns the number of items whating in the queue to be loaded. 93 | */ 94 | public function get numItems():int 95 | { 96 | return _queue.length; 97 | } 98 | /** 99 | * Returns the index of the current texture baing loaded 100 | */ 101 | public function get currentItemIndex():int 102 | { 103 | return _currentItemIndex; 104 | } 105 | 106 | /** 107 | * Returns an array of loader objects containing the loaded images 108 | */ 109 | public function get images():Array 110 | { 111 | var items:Array = []; 112 | for each (var item:LoaderAndRequest in _queue) 113 | { 114 | items.push(item.loader); 115 | } 116 | return items; 117 | } 118 | 119 | /** 120 | * Returns the loader object for the current texture being loaded 121 | */ 122 | public function get currentLoader():TextureLoader 123 | { 124 | return (_queue[currentItemIndex] as LoaderAndRequest).loader; 125 | } 126 | 127 | /** 128 | * Returns the url request object for the current texture being loaded 129 | */ 130 | public function get currentURLRequest():URLRequest 131 | { 132 | return (_queue[currentItemIndex] as LoaderAndRequest).request; 133 | } 134 | 135 | 136 | /** 137 | * Returns the overall progress of the loader queue. 138 | * Progress of 0 means that nothing has loaded. Progress of 1 means that all the items are fully loaded 139 | */ 140 | public function get progress():Number 141 | { 142 | return calcProgress(); 143 | } 144 | 145 | /** 146 | * Returns the overall progress of the loader queue as a percentage. 147 | */ 148 | public function get percentLoaded():Number 149 | { 150 | return progress * 100; 151 | } 152 | 153 | /** 154 | * Creates a new TextureLoadQueue object. 155 | */ 156 | public function TextureLoadQueue() 157 | { 158 | _queue = []; 159 | 160 | } 161 | 162 | /** 163 | * Adds a new loader and request object to the load queue. 164 | * 165 | * @param loader The loader object to add to the queue. 166 | * @param request The url request object to add tp the queue. 167 | */ 168 | public function addItem(loader:TextureLoader, request:URLRequest):void 169 | { 170 | //check to stop duplicated loading 171 | for each (var _item:LoaderAndRequest in _queue) { 172 | if (_item.request.url == request.url) 173 | return; 174 | } 175 | _queue.push(new LoaderAndRequest(loader, request)); 176 | } 177 | 178 | /** 179 | * Starts the load queue loading. 180 | */ 181 | public function start():void 182 | { 183 | _currentItemIndex = 0; 184 | loadNext(); 185 | } 186 | } 187 | } 188 | 189 | import flash.net.URLRequest; 190 | import away3dlite.loaders.utils.TextureLoader; 191 | 192 | 193 | class LoaderAndRequest { 194 | 195 | public var loader:TextureLoader; 196 | public var request:URLRequest; 197 | 198 | public function LoaderAndRequest(loader:TextureLoader, request:URLRequest) 199 | { 200 | this.loader = loader; 201 | this.request = request; 202 | } 203 | } -------------------------------------------------------------------------------- /src/away3dlite/loaders/MD2.as: -------------------------------------------------------------------------------- 1 | package away3dlite.loaders { import away3dlite.animators.*; import away3dlite.animators.frames.Frame; import away3dlite.arcane; import away3dlite.core.utils.*; import flash.utils.*; use namespace arcane; /** * File loader for the Md2 file format. */ public class MD2 extends AbstractParser { /** @private */ arcane override function prepareData(data:*):void { md2 = Cast.bytearray(data); var a:int, b:int, c:int, ta:int, tb:int, tc:int, i1:int, i2:int, i3:int; var i:int, uvs:Array = []; // Make sure to have this in Little Endian or you will hate you life. // At least I did the first time I did this for a while. md2.endian = Endian.LITTLE_ENDIAN; // Read the header and make sure it is valid MD2 file readMd2Header(md2); if (ident != 844121161 || version != 8) throw new Error("Error loading MD2 file: Not a valid MD2 file/bad version"); // UV coordinates // Load them! md2.position = offset_st; for (i = 0; i < num_st; i++) uvs.push(md2.readShort() / skinwidth, (md2.readShort() / skinheight)); mesh._uvtData.length = mesh._vertices.length = num_tris*9; vertices.length = num_tris*3; // Faces // Creates the faces with the proper references to vertices // NOTE: DO NOT change the order of the variable assignments here, // or nothing will work. md2.position = offset_tris; for (i = 0; i < num_tris; i++) { i1 = i*3; i2 = i1 + 1; i3 = i1 + 2; //collect vertices a = md2.readUnsignedShort(); b = md2.readUnsignedShort(); c = md2.readUnsignedShort(); vertices[i1] = a; vertices[i2] = b; vertices[i3] = c; //collect indices mesh._indices.push(i3, i2, i1); //collect face lengths mesh._faceLengths.push(3); //collect uvData ta = md2.readUnsignedShort(); tb = md2.readUnsignedShort(); tc = md2.readUnsignedShort(); mesh._uvtData[i1*3] = uvs[ta*2]; mesh._uvtData[i1*3 + 1] = uvs[ta*2 + 1]; mesh._uvtData[i1*3 + 2] = 1; mesh._uvtData[i2*3] = uvs[tb*2]; mesh._uvtData[i2*3 + 1] = uvs[tb*2 + 1]; mesh._uvtData[i2*3 + 2] = 1; mesh._uvtData[i3*3] = uvs[tc*2]; mesh._uvtData[i3*3 + 1] = uvs[tc*2 + 1]; mesh._uvtData[i3*3 + 2] = 1; } // Frame animation data // This part is a little funky. md2.position = offset_frames; readFrames(md2); //setup vertices for the first frame i = mesh._vertices.length; vertices = mesh.frames[0].vertices; while (i--) mesh._vertices[i] = vertices[i]; if (material) mesh.material = material; mesh.buildFaces(); mesh.type = ".Md2"; } private var md2:ByteArray; private var ident:int; private var version:int; private var skinwidth:int; private var skinheight:int; private var framesize:int; private var num_skins:int; private var num_vertices:int; private var num_st:int; private var num_tris:int; private var num_glcmds:int; private var num_frames:int; private var offset_skins:int; private var offset_st:int; private var offset_tris:int; private var offset_frames:int; private var offset_glcmds:int; private var offset_end:int; private var mesh:MovieMesh; private var vertices:Vector. = new Vector.(); private var minX:Number = Infinity, maxX:Number = -Infinity, minY:Number = Infinity, maxY:Number = -Infinity, minZ:Number = Infinity, maxZ:Number = -Infinity; /** * Reads in all the frames */ private function readFrames(data:ByteArray):void { var sx:Number, sy:Number, sz:Number; var tx:Number, ty:Number, tz:Number; var fvertices:Vector., frame:Frame; var tvertices:Vector.; var i:int, j:int, k:int, char:int; for (i = 0; i < num_frames; i++) { tvertices = new Vector.(); fvertices = new Vector.(num_tris*9, true); frame = new Frame("", fvertices); sx = data.readFloat(); sy = data.readFloat(); sz = data.readFloat(); tx = data.readFloat(); ty = data.readFloat(); tz = data.readFloat(); //read frame name k = 0; for (j = 0; j < 16; j++) { char = data.readUnsignedByte(); if (int(char) >= 0x30 && int(char) <= 0x7A && k < 3) frame.name += String.fromCharCode(char); if (int(char) >= 0x30 && int(char) <= 0x39) k++; } // Note, the extra data.position++ in the for loop is there // to skip over a byte that holds the "vertex normal index" for (j = 0; j < num_vertices; j++, data.position++) tvertices.push((sx*data.readUnsignedByte() + tx)*scaling, (sy*data.readUnsignedByte() + ty)*scaling, (sz*data.readUnsignedByte() + tz)*scaling); for (j = 0; j < num_tris*3; j++) { fvertices[j*3] = tvertices[vertices[j]*3]; fvertices[j*3 + 1] = tvertices[vertices[j]*3 + 1]; fvertices[j*3 + 2] = tvertices[vertices[j]*3 + 2]; //collect min/max for 1 frame only if (centerMeshes && i==0) { minX = (fvertices[j*3]maxX)?fvertices[j*3]:maxX; maxY = (fvertices[j*3+1]>maxY)?fvertices[j*3+1]:maxY; maxZ = (fvertices[j*3+2]>maxZ)?fvertices[j*3+2]:maxZ; } } if (centerMeshes) for (j = 0; j < num_tris*3; j++) { fvertices[j*3] -= (maxX + minX)/2; fvertices[j*3 + 1] -= (maxY + minY)/2; fvertices[j*3 + 2] -= (maxZ + minZ)/2; } mesh.addFrame(frame); } vertices.fixed = true; } /** * Reads in all that MD2 Header data that is declared as private variables. * I know its a lot, and it looks ugly, but only way to do it in Flash */ private function readMd2Header(data:ByteArray):void { ident = data.readInt(); version = data.readInt(); skinwidth = data.readInt(); skinheight = data.readInt(); framesize = data.readInt(); num_skins = data.readInt(); num_vertices = data.readInt(); num_st = data.readInt(); num_tris = data.readInt(); num_glcmds = data.readInt(); num_frames = data.readInt(); offset_skins = data.readInt(); offset_st = data.readInt(); offset_tris = data.readInt(); offset_frames = data.readInt(); offset_glcmds = data.readInt(); offset_end = data.readInt(); } /** * A scaling factor for all geometry in the model. Defaults to 1. */ public var scaling:Number = 1; /** * Controls the automatic centering of geometry data in the model, improving culling and the accuracy of bounding dimension values. */ public var centerMeshes:Boolean; /** * Creates a new Md2 object. */ public function MD2() { mesh = (_container = new MovieMesh()) as MovieMesh; binary = true; } } } -------------------------------------------------------------------------------- /src/away3dlite/core/render/BasicRenderer.as: -------------------------------------------------------------------------------- 1 | package away3dlite.core.render 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.containers.*; 5 | import away3dlite.core.base.*; 6 | import away3dlite.materials.*; 7 | 8 | import flash.display.*; 9 | import flash.utils.Dictionary; 10 | 11 | use namespace arcane; 12 | 13 | /** 14 | * Standard renderer for a view. 15 | * 16 | * @see away3dlite.containers.View3D 17 | */ 18 | public class BasicRenderer extends Renderer 19 | { 20 | private var _mesh:Mesh; 21 | private var _screenVertices:Vector.; 22 | private var _uvtData:Vector.; 23 | private var _material:Material; 24 | private var _i:int; 25 | private var _j:int; 26 | private var _k:int; 27 | 28 | private var _material_graphicsData:Vector.; 29 | 30 | // Layer 31 | private var _graphicsDatas:Dictionary = new Dictionary(true); 32 | 33 | private function collectFaces(object:Object3D):void 34 | { 35 | if (!object.visible || object._perspCulling) 36 | return; 37 | 38 | _mouseEnabledArray.push(_mouseEnabled); 39 | _mouseEnabled = object._mouseEnabled = (_mouseEnabled && object.mouseEnabled); 40 | 41 | if (object is ObjectContainer3D) { 42 | var children:Array = (object as ObjectContainer3D).children; 43 | var child:Object3D; 44 | 45 | for each (child in children) 46 | { 47 | if(child.layer) 48 | child.layer.graphics.clear(); 49 | 50 | collectFaces(child); 51 | } 52 | 53 | } 54 | 55 | if (object is Mesh) { 56 | var mesh:Mesh = object as Mesh; 57 | _clipping.collectFaces(mesh, _faces); 58 | 59 | if (_view.mouseEnabled && _mouseEnabled) 60 | collectScreenVertices(mesh); 61 | 62 | _view._totalFaces += mesh._faces.length; 63 | } 64 | 65 | _mouseEnabled = _mouseEnabledArray.pop(); 66 | 67 | ++_view._totalObjects; 68 | ++_view._renderedObjects; 69 | } 70 | 71 | /** @private */ 72 | protected override function sortFaces():void 73 | { 74 | super.sortFaces(); 75 | 76 | //reorder indices 77 | _material = null; 78 | _mesh = null; 79 | 80 | i = -1; 81 | while (i++ < 255) { 82 | j = q1[i]; 83 | while (j) { 84 | _face = _faces[j-1]; 85 | 86 | if (_material != _face.material) 87 | { 88 | if (_material) 89 | { 90 | _material_graphicsData[_material.trianglesIndex] = _triangles; 91 | 92 | if(_mesh.layer) 93 | { 94 | _mesh.layer.graphics.drawGraphicsData(_material_graphicsData); 95 | _graphicsDatas[_material_graphicsData] = _mesh.layer; 96 | }else{ 97 | _view_graphics_drawGraphicsData(_material_graphicsData); 98 | } 99 | } 100 | 101 | //clear vectors by overwriting with a new instance (length = 0 leaves garbage) 102 | _ind = _triangles.indices = new Vector.(); 103 | _vert = _triangles.vertices = new Vector.(); 104 | _uvt = _triangles.uvtData = new Vector.(); 105 | _i = -1; 106 | _j = -1; 107 | _k = -1; 108 | 109 | _mesh = _face.mesh; 110 | _material = _face.material; 111 | _material_graphicsData = _material.graphicsData; 112 | _screenVertices = _mesh._screenVertices; 113 | _uvtData = _mesh._uvtData; 114 | _faceStore = new Vector.(_mesh._vertices.length/3, true); 115 | } else if (_mesh != _face.mesh) { 116 | _mesh = _face.mesh; 117 | _screenVertices = _mesh._screenVertices; 118 | _uvtData = _mesh._uvtData; 119 | _faceStore = new Vector.(_mesh._vertices.length/3, true); 120 | } 121 | 122 | if (_faceStore[_face.i0]) { 123 | _ind[++_i] = _faceStore[_face.i0] - 1; 124 | } else { 125 | _vert[++_j] = _screenVertices[_face.x0]; 126 | _faceStore[_face.i0] = (_ind[++_i] = _j*.5) + 1; 127 | _vert[++_j] = _screenVertices[_face.y0]; 128 | 129 | _uvt[++_k] = _uvtData[_face.u0]; 130 | _uvt[++_k] = _uvtData[_face.v0]; 131 | _uvt[++_k] = _uvtData[_face.t0]; 132 | } 133 | 134 | if (_faceStore[_face.i1]) { 135 | _ind[++_i] = _faceStore[_face.i1] - 1; 136 | } else { 137 | _vert[++_j] = _screenVertices[_face.x1]; 138 | _faceStore[_face.i1] = (_ind[++_i] = _j*.5) + 1; 139 | _vert[++_j] = _screenVertices[_face.y1]; 140 | 141 | _uvt[++_k] = _uvtData[_face.u1]; 142 | _uvt[++_k] = _uvtData[_face.v1]; 143 | _uvt[++_k] = _uvtData[_face.t1]; 144 | } 145 | 146 | if (_faceStore[_face.i2]) { 147 | _ind[++_i] = _faceStore[_face.i2] - 1; 148 | } else { 149 | _vert[++_j] = _screenVertices[_face.x2]; 150 | _faceStore[_face.i2] = (_ind[++_i] = _j*.5) + 1; 151 | _vert[++_j] = _screenVertices[_face.y2]; 152 | 153 | _uvt[++_k] = _uvtData[_face.u2]; 154 | _uvt[++_k] = _uvtData[_face.v2]; 155 | _uvt[++_k] = _uvtData[_face.t2]; 156 | } 157 | 158 | if (_face.i3) { 159 | _ind[++_i] = _faceStore[_face.i0] - 1; 160 | _ind[++_i] = _faceStore[_face.i2] - 1; 161 | 162 | if (_faceStore[_face.i3]) { 163 | _ind[++_i] = _faceStore[_face.i3] - 1; 164 | } else { 165 | _vert[++_j] = _screenVertices[_face.x3]; 166 | _faceStore[_face.i3] = (_ind[++_i] = _j*.5) + 1; 167 | _vert[++_j] = _screenVertices[_face.y3]; 168 | 169 | _uvt[++_k] = _uvtData[_face.u3]; 170 | _uvt[++_k] = _uvtData[_face.v3]; 171 | _uvt[++_k] = _uvtData[_face.t3]; 172 | } 173 | } 174 | 175 | j = np1[j]; 176 | } 177 | } 178 | } 179 | 180 | /** 181 | * Creates a new BasicRenderer object. 182 | */ 183 | public function BasicRenderer() 184 | { 185 | super(); 186 | } 187 | 188 | /** 189 | * @inheritDoc 190 | */ 191 | public override function getFaceUnderPoint(x:Number, y:Number):Face 192 | { 193 | if (!_faces.length) 194 | return null; 195 | 196 | collectPointVertices(x, y); 197 | 198 | _screenZ = 0; 199 | 200 | collectPointFace(x, y); 201 | 202 | return _pointFace; 203 | } 204 | 205 | /** 206 | * @inheritDoc 207 | */ 208 | public override function render():void 209 | { 210 | super.render(); 211 | 212 | _faces = new Vector.(); 213 | 214 | collectFaces(_scene); 215 | 216 | _faces.fixed = true; 217 | 218 | _view._renderedFaces = _faces.length; 219 | 220 | if (!_faces.length) 221 | return; 222 | 223 | _sort.fixed = false; 224 | _sort.length = _faces.length; 225 | _sort.fixed = true; 226 | 227 | sortFaces(); 228 | 229 | if (_material) 230 | { 231 | _material_graphicsData = _material.graphicsData; 232 | _material_graphicsData[_material.trianglesIndex] = _triangles; 233 | 234 | // draw to layer 235 | if(_graphicsDatas[_material_graphicsData]) 236 | { 237 | _graphicsDatas[_material_graphicsData].graphics.drawGraphicsData(_material_graphicsData); 238 | _material_graphicsData = null; 239 | } 240 | 241 | // draw to view 242 | if(_material_graphicsData) 243 | _view_graphics_drawGraphicsData(_material_graphicsData); 244 | } 245 | 246 | } 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /src/away3dlite/primitives/Cone.as: -------------------------------------------------------------------------------- 1 | package away3dlite.primitives 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.core.base.*; 5 | import away3dlite.materials.*; 6 | 7 | use namespace arcane; 8 | 9 | /** 10 | * Creates a 3d cone primitive. 11 | */ 12 | public class Cone extends AbstractPrimitive 13 | { 14 | private var jMin:int; 15 | private var _radius:Number = 100; 16 | private var _height:Number = 200; 17 | private var _segmentsW:int = 8; 18 | private var _segmentsH:int = 1; 19 | private var _openEnded:Boolean = false; 20 | private var _yUp:Boolean = true; 21 | 22 | /** 23 | * @inheritDoc 24 | */ 25 | protected override function buildPrimitive():void 26 | { 27 | super.buildPrimitive(); 28 | 29 | var i:int; 30 | var j:int; 31 | 32 | _height /= 2; 33 | 34 | if (!_openEnded) { 35 | jMin = 1; 36 | _segmentsH += 1; 37 | 38 | for (i = 0; i <= _segmentsW; ++i) { 39 | _yUp? _vertices.push(0, _height, 0) : _vertices.push(0, 0, -_height); 40 | _uvtData.push(i/_segmentsW, 1, 1); 41 | } 42 | } else { 43 | jMin = 0; 44 | } 45 | 46 | for (j = jMin; j < _segmentsH; ++j) { 47 | var z:Number = -_height + 2*_height*(j - jMin)/(_segmentsH - jMin); 48 | 49 | for (i = 0; i <= _segmentsW; ++i) { 50 | var verangle:Number = 2*Math.PI*i/_segmentsW; 51 | var ringradius:Number = _radius*(_segmentsH - j)/(_segmentsH - jMin); 52 | var x:Number = ringradius*Math.cos(verangle); 53 | var y:Number = ringradius*Math.sin(verangle); 54 | 55 | _yUp? _vertices.push(x, -z, y) : _vertices.push(x, y, z); 56 | 57 | _uvtData.push(i/_segmentsW, 1 - j/_segmentsH, 1); 58 | } 59 | } 60 | 61 | for (i = 0; i <= _segmentsW; ++i) { 62 | _yUp? _vertices.push(0, -_height, 0) : _vertices.push(0, 0, _height); 63 | _uvtData.push(i/_segmentsW, 0, 1); 64 | } 65 | 66 | for (j = 1; j <= _segmentsH; ++j) { 67 | for (i = 1; i <= _segmentsW; ++i) { 68 | var a:int = (_segmentsW + 1)*j + i; 69 | var b:int = (_segmentsW + 1)*j + i - 1; 70 | var c:int = (_segmentsW + 1)*(j - 1) + i - 1; 71 | var d:int = (_segmentsW + 1)*(j - 1) + i; 72 | 73 | if (j == _segmentsH) { 74 | _indices.push(a,c,d); 75 | _faceLengths.push(3); 76 | } else if (j == jMin) { 77 | _indices.push(a,b,c); 78 | _faceLengths.push(3); 79 | } else { 80 | _indices.push(a,b,c,d); 81 | _faceLengths.push(4); 82 | } 83 | } 84 | } 85 | 86 | if (!_openEnded) 87 | _segmentsH -= 1; 88 | 89 | _height *=2; 90 | } 91 | 92 | /** 93 | * Defines the radius of the cone base. Defaults to 100. 94 | */ 95 | public function get radius():Number 96 | { 97 | return _radius; 98 | } 99 | 100 | public function set radius(val:Number):void 101 | { 102 | if (_radius == val) 103 | return; 104 | 105 | _radius = val; 106 | _primitiveDirty = true; 107 | } 108 | 109 | /** 110 | * Defines the height of the cone. Defaults to 200. 111 | */ 112 | public override function get height():Number 113 | { 114 | return _height; 115 | } 116 | 117 | public override function set height(val:Number):void 118 | { 119 | if (_height == val) 120 | return; 121 | 122 | _height = val; 123 | _primitiveDirty = true; 124 | } 125 | 126 | /** 127 | * Defines the number of horizontal segments that make up the cone. Defaults to 8. 128 | */ 129 | public function get segmentsW():int 130 | { 131 | return _segmentsW; 132 | } 133 | 134 | public function set segmentsW(val:int):void 135 | { 136 | if (_segmentsW == val) 137 | return; 138 | 139 | _segmentsW = val; 140 | _primitiveDirty = true; 141 | } 142 | 143 | /** 144 | * Defines the number of vertical segments that make up the cone. Defaults to 1. 145 | */ 146 | public function get segmentsH():int 147 | { 148 | return _segmentsH; 149 | } 150 | 151 | public function set segmentsH(val:int):void 152 | { 153 | if (_segmentsH == val) 154 | return; 155 | 156 | _segmentsH = val; 157 | _primitiveDirty = true; 158 | } 159 | 160 | /** 161 | * Defines whether the end of the cone is left open (true) or closed (false). Defaults to false. 162 | */ 163 | public function get openEnded():Boolean 164 | { 165 | return _openEnded; 166 | } 167 | 168 | public function set openEnded(val:Boolean):void 169 | { 170 | if (_openEnded == val) 171 | return; 172 | 173 | _openEnded = val; 174 | _primitiveDirty = true; 175 | } 176 | 177 | /** 178 | * Defines whether the coordinates of the cone points use a yUp orientation (true) or a zUp orientation (false). Defaults to true. 179 | */ 180 | public function get yUp():Boolean 181 | { 182 | return _yUp; 183 | } 184 | 185 | public function set yUp(val:Boolean):void 186 | { 187 | if (_yUp == val) 188 | return; 189 | 190 | _yUp = val; 191 | _primitiveDirty = true; 192 | } 193 | 194 | /** 195 | * Creates a new Cone object. 196 | * 197 | * @param material Defines the global material used on the faces in the cone. 198 | * @param radius Defines the radius of the cone base. 199 | * @param height Defines the height of the cone. 200 | * @param segmentsW Defines the number of horizontal segments that make up the cone. 201 | * @param segmentsH Defines the number of vertical segments that make up the cone. 202 | * @param openEnded Defines whether the end of the cone is left open (true) or closed (false). 203 | * @param yUp Defines whether the coordinates of the cone points use a yUp orientation (true) or a zUp orientation (false). 204 | */ 205 | public function Cone(material:Material = null, radius:Number = 100, height:Number = 200, segmentsW:int = 8, segmentsH:int = 1, openEnded:Boolean = true, yUp:Boolean = true) 206 | { 207 | super(material); 208 | 209 | _radius = radius; 210 | _height = height; 211 | _segmentsW = segmentsW; 212 | _segmentsH = segmentsH; 213 | _openEnded = openEnded; 214 | _yUp = yUp; 215 | 216 | type = "Cone"; 217 | url = "primitive"; 218 | } 219 | 220 | /** 221 | * Duplicates the cone properties to another Cone object. 222 | * 223 | * @param object [optional] The new object instance into which all properties are copied. The default is Cone. 224 | * @return The new object instance with duplicated properties applied. 225 | */ 226 | public override function clone(object:Object3D = null):Object3D 227 | { 228 | var cone:Cone = (object as Cone) || new Cone(); 229 | super.clone(cone); 230 | cone.radius = _radius; 231 | cone.height = _height; 232 | cone.segmentsW = _segmentsW; 233 | cone.segmentsH = _segmentsH; 234 | cone.openEnded = _openEnded; 235 | cone.yUp = _yUp; 236 | cone._primitiveDirty = false; 237 | 238 | return cone; 239 | } 240 | } 241 | } -------------------------------------------------------------------------------- /src/away3dlite/core/render/Renderer.as: -------------------------------------------------------------------------------- 1 | package away3dlite.core.render 2 | { 3 | import away3dlite.arcane; 4 | import away3dlite.containers.*; 5 | import away3dlite.core.base.*; 6 | import away3dlite.core.clip.*; 7 | 8 | import flash.display.*; 9 | 10 | use namespace arcane; 11 | 12 | /** 13 | * @author robbateman 14 | */ 15 | public class Renderer 16 | { 17 | /** @private */ 18 | arcane function setView(view:View3D):void 19 | { 20 | _view = view; 21 | _view_graphics_drawGraphicsData = _view.graphics.drawGraphicsData; 22 | } 23 | 24 | private var k:int; 25 | private var q0:Vector.; 26 | private var np0:Vector.; 27 | private var _screenVertexArrays:Vector.> = new Vector.>(); 28 | private var _screenVertices:Vector.; 29 | private var _screenPointVertexArrays:Vector.> = new Vector.>(); 30 | private var _screenPointVertices:Vector.; 31 | private var _index:int; 32 | private var _indexX:int; 33 | private var _indexY:int; 34 | /** @private */ 35 | protected var i:int; 36 | /** @private */ 37 | protected var j:int; 38 | /** @private */ 39 | protected var q1:Vector.; 40 | /** @private */ 41 | protected var np1:Vector.; 42 | /** @private */ 43 | protected var _view:View3D; 44 | /** @private */ 45 | protected var _scene:Scene3D; 46 | /** @private */ 47 | protected var _face:Face; 48 | /** @private */ 49 | protected var _faces:Vector. = new Vector.(); 50 | /** @private */ 51 | protected var _sort:Vector. = new Vector.(); 52 | /** @private */ 53 | protected var _faceStore:Vector. = new Vector.(); 54 | /** @private */ 55 | protected var _clipping:Clipping; 56 | /** @private */ 57 | protected var _screenZ:int; 58 | /** @private */ 59 | protected var _pointFace:Face; 60 | /** @private */ 61 | protected var _mouseEnabled:Boolean; 62 | /** @private */ 63 | protected var _mouseEnabledArray:Vector. = new Vector.(); 64 | /** @private */ 65 | protected var _ind:Vector.; 66 | /** @private */ 67 | protected var _vert:Vector.; 68 | /** @private */ 69 | protected var _uvt:Vector.; 70 | /** @private */ 71 | protected var _triangles:GraphicsTrianglePath = new GraphicsTrianglePath(); 72 | /** @private */ 73 | protected var _view_graphics_drawGraphicsData:Function; 74 | 75 | /** @private */ 76 | protected function sortFaces():void 77 | { 78 | // by pass 79 | var _faces_length_1:int = int(_faces.length + 1); 80 | 81 | q0 = new Vector.(256, true); 82 | q1 = new Vector.(256, true); 83 | np0 = new Vector.(_faces_length_1, true); 84 | np1 = new Vector.(_faces_length_1, true); 85 | 86 | i = 0; 87 | j = 0; 88 | 89 | for each (_face in _faces) { 90 | np0[int(i+1)] = q0[k = (255 & (_sort[i] = _face.calculateScreenZ()))]; 91 | q0[k] = int(++i); 92 | } 93 | 94 | i = 256; 95 | while (i--) { 96 | j = q0[i]; 97 | while (j) { 98 | np1[j] = q1[k = (65280 & _sort[int(j-1)]) >> 8]; 99 | j = np0[q1[k] = j]; 100 | } 101 | } 102 | } 103 | 104 | /** @private */ 105 | protected function collectPointFace(x:Number, y:Number):void 106 | { 107 | var pointCount:int; 108 | var pointTotal:int; 109 | var pointCountX:int; 110 | var pointCountY:int; 111 | var i:int = _faces.length; 112 | while (i--) { 113 | if (_screenZ < _sort[i] && (_face = _faces[i]).mesh._mouseEnabled) { 114 | _screenPointVertices = _screenPointVertexArrays[_face.mesh._vertexId]; 115 | 116 | if (_face.i3) { 117 | pointTotal = 4; 118 | pointCount = _screenPointVertices[_face.i0] + _screenPointVertices[_face.i1] + _screenPointVertices[_face.i2] + _screenPointVertices[_face.i3]; 119 | } else { 120 | pointTotal = 3; 121 | pointCount = _screenPointVertices[_face.i0] + _screenPointVertices[_face.i1] + _screenPointVertices[_face.i2]; 122 | } 123 | pointCountX = (pointCount >> 4); 124 | pointCountY = (pointCount & 15); 125 | if (pointCountX && pointCountX < pointTotal && pointCountY && pointCountY < pointTotal) { 126 | 127 | //flagged for edge detection 128 | var vertices:Vector. = _face.mesh._screenVertices; 129 | var v0x:Number = vertices[_face.x0]; 130 | var v0y:Number = vertices[_face.y0]; 131 | var v1x:Number = vertices[_face.x1]; 132 | var v1y:Number = vertices[_face.y1]; 133 | var v2x:Number = vertices[_face.x2]; 134 | var v2y:Number = vertices[_face.y2]; 135 | 136 | if ((v0x*(y - v1y) + v1x*(v0y - y) + x*(v1y - v0y)) < -0.001) 137 | continue; 138 | 139 | if ((x*(v2y - v1y) + v1x*(y - v2y) + v2x*(v1y - y)) < -0.001) 140 | continue; 141 | 142 | if (_face.i3) { 143 | var v3x:Number = vertices[_face.x3]; 144 | var v3y:Number = vertices[_face.y3]; 145 | 146 | if ((v3x*(v2y - y) + x*(v3y - v2y) + v2x*(y - v3y)) < -0.001) 147 | continue; 148 | 149 | if ((v0x*(v3y - y) + x*(v0y - v3y) + v3x*(y - v0y)) < -0.001) 150 | continue; 151 | 152 | } else if ((v0x*(v2y - y) + x*(v0y - v2y) + v2x*(y - v0y)) < -0.001) { 153 | continue; 154 | } 155 | 156 | _screenZ = _sort[i]; 157 | _pointFace = _face; 158 | } 159 | } 160 | } 161 | } 162 | 163 | /** @private */ 164 | protected function collectScreenVertices(mesh:Mesh):void 165 | { 166 | mesh._vertexId = _screenVertexArrays.length; 167 | _screenVertexArrays.push(mesh._screenVertices); 168 | } 169 | 170 | /** @private */ 171 | protected function collectPointVertices(x:Number, y:Number):void 172 | { 173 | _screenPointVertexArrays.fixed = false; 174 | _screenPointVertexArrays.length = _screenVertexArrays.length; 175 | _screenPointVertexArrays.fixed = true; 176 | 177 | var i:int = _screenVertexArrays.length; 178 | 179 | while (i--) { 180 | _screenVertices = _screenVertexArrays[i]; 181 | _screenPointVertices = _screenPointVertexArrays[i] = new Vector.(_index = _screenVertices.length/2, true); 182 | 183 | while (_index--) { 184 | _indexY = (_indexX = _index*2) + 1; 185 | 186 | if (_screenVertices[_indexX] < x) 187 | _screenPointVertices[_index] += 0x10; 188 | 189 | if (_screenVertices[_indexY] < y) 190 | _screenPointVertices[_index] += 0x1; 191 | } 192 | } 193 | } 194 | 195 | /** 196 | * Creates a new Renderer object. 197 | */ 198 | function Renderer() 199 | { 200 | _ind = _triangles.indices = new Vector.(); 201 | _vert = _triangles.vertices = new Vector.(); 202 | _uvt = _triangles.uvtData = new Vector.(); 203 | } 204 | 205 | /** 206 | * Returns the face object directly under the given point. 207 | * 208 | * @param x The x coordinate of the point. 209 | * @param y The y coordinate of the point. 210 | */ 211 | public function getFaceUnderPoint(x:Number, y:Number):Face 212 | { 213 | x; 214 | y; 215 | return null; 216 | } 217 | 218 | /** 219 | * Renders the contents of the scene to the view. 220 | * 221 | * @see awa3dlite.containers.Scene3D 222 | * @see awa3dlite.containers.View3D 223 | */ 224 | public function render():void 225 | { 226 | _scene = _view.scene; 227 | 228 | _clipping = _view.screenClipping; 229 | 230 | _mouseEnabled = _scene.mouseEnabled; 231 | _mouseEnabledArray.length = 0; 232 | _pointFace = null; 233 | 234 | _screenVertexArrays.length = 0; 235 | } 236 | } 237 | } 238 | --------------------------------------------------------------------------------