forked from: Hero
forked from Hero (diff: 2)
AWD file loading example in Away3d Demonstrates: How to use the Loader3D object to load an embedded internal awd model. How to create character interaction How to set custom material on a model. Code, model and map by LoTh 3dflashlo@gmail.com - http://3dflashlo.wordpress.com/ Get 3dsmax file & model https://github.com/lo-th/loth_labs Code reference https://github.com/away3d/away3d-examples-fp11/ Intermediate_CharacterAnimation.as by Rob Bateman
ActionScript3 source code
/**
* Copyright hemingway ( http://wonderfl.net/user/hemingway )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/iYzI
*/
// forked from Loth2012's Hero
/*
AWD file loading example in Away3d
Demonstrates:
How to use the Loader3D object to load an embedded internal awd model.
How to create character interaction
How to set custom material on a model.
Code, model and map by LoTh
3dflashlo@gmail.com - http://3dflashlo.wordpress.com/
Get 3dsmax file & model https://github.com/lo-th/loth_labs
Code reference https://github.com/away3d/away3d-examples-fp11/
Intermediate_CharacterAnimation.as by Rob Bateman
*/
package {
import away3d.animators.transitions.CrossfadeStateTransition;
import away3d.animators.SkeletonAnimationState;
import away3d.animators.SkeletonAnimationSet;
import away3d.animators.SkeletonAnimator;
import away3d.animators.data.Skeleton;
import away3d.lights.shadowmaps.NearDirectionalShadowMapper;
import away3d.materials.methods.FilteredShadowMapMethod;
import away3d.materials.methods.NearShadowMapMethod;
import away3d.utils.Cast;
import away3d.core.managers.Stage3DManager;
import away3d.core.managers.Stage3DProxy;
import away3d.events.Stage3DEvent;
import away3d.entities.Mesh;
import away3d.debug.AwayStats;
import away3d.primitives.SkyBox;
import away3d.lights.LightBase;
import away3d.loaders.Loader3D;
import away3d.lights.LightProbe;
import away3d.lights.PointLight;
import away3d.events.LoaderEvent;
import away3d.containers.View3D;
import away3d.events.AssetEvent;
import away3d.core.base.Geometry;
import away3d.events.MouseEvent3D;
import away3d.library.AssetLibrary;
import away3d.materials.LightSources;
import away3d.textures.BitmapTexture;
import away3d.materials.ColorMaterial;
import away3d.lights.DirectionalLight;
import away3d.library.assets.AssetType;
import away3d.loaders.parsers.AWD2Parser;
import away3d.materials.methods.FogMethod;
import away3d.materials.methods.EnvMapMethod;
import away3d.materials.methods.LightMapMethod;
import away3d.materials.methods.FresnelSpecularMethod;
import away3d.materials.methods.TripleFilteredShadowMapMethod;
import away3d.materials.lightpickers.StaticLightPicker;
import away3d.cameras.lenses.PerspectiveLens;
import away3d.materials.DefaultMaterialBase;
import away3d.controllers.HoverController;
import away3d.materials.TextureMaterial;
import away3d.primitives.SphereGeometry;
import away3d.primitives.PlaneGeometry;
import flash.filters.DropShadowFilter;
import flash.display.StageScaleMode;
import flash.display.StageQuality;
import flash.events.KeyboardEvent;
import flash.display.BitmapData;
import flash.display.StageAlign;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.display.LoaderInfo;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.Sprite;
import flash.geom.Vector3D;
import flash.events.Event;
import flash.geom.Matrix;
import flash.ui.Keyboard;
import flash.net.URLRequest;
import flash.display.DisplayObject;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
public class Hero extends Sprite {
private var _manager:Stage3DManager;
private var _stage3DProxy:Stage3DProxy;
// demo color [ light color 1, light color 2, sky color, ground color]
private var DemoColor:Array = [0xAAAAA9, 0x333338, 0x445465, 0x333338];
private var DemoAmbiant:Array = [0.4, 0.2];
private var DemoDiffuse:Array = [1, 0.5];
private var DemoSpecular:Array = [1, 0.5];
private var _capture : Bitmap;
// mapping
private const referenceLink:String = "http://3dflashlo.free.fr/wonderfl/"
private const referenceMap:Array = ['onkba_N.png', 'onkba_NORM.jpg', 'onkba_OCL.jpg', 'gun_N.jpg', 'gun_NORM.jpg', 'gun_OCL.jpg', 'floor_N.jpg', 'floor_NORM.jpg', 'floor_OCL.jpg'];
private var _mapList:Vector.<BitmapData>;
private var n:Number = 0;
//engine variables
private var _view:View3D;
private var _stats:AwayStats;
private var _lightPicker:StaticLightPicker;
private var _hoverCtrl:HoverController;
private var _skyBox:SkyBox;
//referency
private var _materials:Vector.<DefaultMaterialBase>;
private var _light:Array;
//animation variables
private var stateTransition:CrossfadeStateTransition = new CrossfadeStateTransition(0.5);
private var animator:SkeletonAnimator;
private var animationSet:SkeletonAnimationSet;
private var currentRotationInc:Number = 0;
private var movementDirection:Number;
private var isRunning:Boolean;
private var isMoving:Boolean;
private var isJumping:Boolean;
private var currentAnim:String;
//animation constants
private const ANIM_BREATHE:String = "Breathe";
private const ANIM_WALK:String = "Walk";
private const ANIM_RUN:String = "Run";
private const ANIM_JUMP:String = "Jump";
private const ANIM_FIGHT:String = "Fight";
private const ANIM_BOXE:String = "Boxe";
private const XFADE_TIME:Number = 0.5;
private const ROTATION_SPEED:Number = 3;
private const RUN_SPEED:Number = 2;
private const WALK_SPEED:Number = 1;
private const BREATHE_SPEED:Number = 1;
private const JUMP_SPEED:Number = 1;
private const BOXE_SPEED:Number = 1.6;
private const FIGHT_SPEED:Number = 1.5;
//scene objects
private var hero:Mesh;
private var gun:Mesh;
private var ground:Mesh;
//advanced eye
private var _heroPieces:Mesh;
private var _eyes:Mesh;
private var _eyeL:Mesh;
private var _eyeR:Mesh;
private var _eyesTarget:Mesh;
private var _eyeCount:int = 0;
private var _eyeMapClose:ColorMaterial;
private var _eyeMapOpen:TextureMaterial;
private var _eyeLook:Mesh;
//navigation
private var _prevMouseX:Number;
private var _prevMouseY:Number;
private var _mouseMove:Boolean;
private var _cameraHeight:Number = 0;
private var _eyePosition:Vector3D;
private var cloneActif:Boolean = false;
private var _mapper:Mapper;
private var _text:TextField;
private var _fog:FogMethod;
private var _fog2:FogMethod;
private var _reflect:EnvMapMethod;
private var _specularMethod:FresnelSpecularMethod;
private var _shadowMethod:NearShadowMapMethod;
/**
* Constructor
*/
public function Hero() {
if (stage)
init();
else
addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
}
//--------------------------------------------------------------------- ENGINE
private function init(e:Event = null):void{
stage.frameRate = 60;
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.align = 'TL';
stage.scaleMode = 'noScale';
stage.quality = 'low';
// ★wonderfl capture
Wonderfl.disable_capture();
// _capture = addChild(new Bitmap(new BitmapData(465, 465, false, 0x000000))) as Bitmap ;
_manager = Stage3DManager.getInstance(stage);
_stage3DProxy = _manager.getFreeStage3DProxy();
_stage3DProxy.addEventListener(Stage3DEvent.CONTEXT3D_CREATED, onContextCreated);
}
private function onContextCreated(e:Stage3DEvent):void{
_stage3DProxy.color = DemoColor[0];
_stage3DProxy.antiAlias = 4;
_stage3DProxy.width = stage.stageWidth;
_stage3DProxy.height = stage.stageHeight;
initEngine();
initText();
initLights();
initListeners();
// start by loading all bitmap
_mapList = new Vector.<BitmapData>();
load(referenceLink+'assets/' + referenceMap[n]);
}
/**
* Initialise the engine
*/
private function initEngine():void {
_view = new View3D();
_view.stage3DProxy = _stage3DProxy;
_view.shareContext = true;
_view.backgroundColor = DemoColor[3];
_view.camera.lens = new PerspectiveLens(70);
_view.camera.lens.far = 30000;
_view.camera.lens.near = 1;
_hoverCtrl = new HoverController(_view.camera, null, 180, 0, 1000, 10, 90);
_hoverCtrl.tiltAngle = 0;
_hoverCtrl.panAngle = 180;
_hoverCtrl.minTiltAngle = -60;
_hoverCtrl.maxTiltAngle = 60;
_hoverCtrl.autoUpdate = false;
addChild(_view);
//away3d stat
_stats = new AwayStats(_view, true, true);
addChild(_stats);
//material reference
_materials = new Vector.<DefaultMaterialBase>();
//light referency
_light = [];
//auto map generator
_mapper = new Mapper();
}
//--------------------------------------------------------------------- LOOP
/**
* Render loop
*/
private function onEnterFrame(event:Event):void {
//update character animation
if (hero) {
hero.rotationY += currentRotationInc;
updateEye();
_hoverCtrl.lookAtPosition = new Vector3D(hero.x, _cameraHeight, hero.z);
}
//update camera controler
_hoverCtrl.update();
//update light
_light[1].position = _view.camera.position;
//update view
_view.render();
// ★ wonderfl capture
if (_capture) _stage3DProxy.context3D.drawToBitmapData(_capture.bitmapData);
}
//--------------------------------------------------------------------- LISTENER
/**
* Initialise the listeners
*/
private function initListeners():void {
//add render loop
_stage3DProxy.addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
//add key listeners
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, false, 0, true);
//navigation
stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown, false, 0, true);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove, false, 0, true);
stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseLeave, false, 0, true);
stage.addEventListener(MouseEvent.MOUSE_WHEEL, onStageMouseWheel, false, 0, true)
stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave, false, 0, true);
//add resize event
stage.addEventListener(Event.RESIZE, onResize, false, 0, true);
onResize();
}
//--------------------------------------------------------------------- LIGHT
/**
* Initialise the lights
*/
private function initLights():void {
//create a light for shadows that mimics the sun's position in the skybox
var sun:DirectionalLight = new DirectionalLight(-0.5, -1, 0.3);
sun.castsShadows = true;
sun.shadowMapper = new NearDirectionalShadowMapper(.1);
_view.scene.addChild(sun);
_light.push(sun);
//create a light for ambient effect that mimics the sky
var moon:PointLight = new PointLight();
moon.y = 500;
moon.radius = 1000;
moon.fallOff = 2500;
_view.scene.addChild(moon);
_light.push(moon);
makeSky();
}
//--------------------------------------------------------------------- SKY
/**
* sky change
*/
private function randomSky():void {
DemoColor = [0xFFFFFF * Math.random(), 0xFFFFFF * Math.random(), 0xFFFFFF * Math.random(), 0xFFFFFF * Math.random()];
DemoAmbiant = [0.4, 0.3];
DemoAmbiant = [Math.random(), Math.random()];
DemoDiffuse = [Math.random(), Math.random()];
DemoSpecular = [Math.random() * 4, Math.random() * 2];
makeSky();
}
private function makeSky():void {
if (_light[2]) {
_view.scene.removeChild(_light[2]);
_light.pop();
}
if (_skyBox) {
_view.scene.removeChild(_skyBox);
_skyBox.dispose();
}
//generate vector degrade sky
_mapper.vectorSky([DemoColor[3], DemoColor[3], DemoColor[2]], 8);
_skyBox = new SkyBox(_mapper.sky);
_view.scene.addChild(_skyBox);
//add new probe light
var probe:LightProbe = new LightProbe(_mapper.sky);
_view.scene.addChild(probe);
_light.push(probe);
_light[0].color = DemoColor[0];
_light[0].ambient = DemoAmbiant[0];
_light[0].diffuse = DemoDiffuse[0];
_light[0].specular = DemoSpecular[0];
_light[0].ambientColor = DemoColor[0];
_light[1].color = DemoColor[1];
_light[1].ambient = DemoAmbiant[1];
_light[1].diffuse = DemoDiffuse[1];
_light[1].specular = DemoSpecular[1];
_light[1].ambientColor = DemoColor[1];
_lightPicker = new StaticLightPicker(_light);
for each (var o:DefaultMaterialBase in _materials) {
if (o.name == 'ground') {
o.removeMethod(_fog);
o.removeMethod(_reflect);
_fog = new FogMethod(1000, 10000, DemoColor[3]);
//_reflect = new EnvMapMethod(_mapper.sky, 0.5)
o.addMethod(_fog);
//o.addMethod(_reflect);
}
o.lightPicker = _lightPicker;
}
}
//--------------------------------------------------------------------- MATERIAL
/**
* Initialise the material
*/
protected function initMaterial():void {
log('humm')
//global methode
// _fog = new FogMethod(1000, 10000, DemoColor[3]);
_fog = new FogMethod(0, _view.camera.lens.far, DemoColor[3]);
// _fog2 = new FogMethod(1000, 10000, DemoColor[3]);
_reflect = new EnvMapMethod(_mapper.sky, 0.5)
_specularMethod = new FresnelSpecularMethod();
_specularMethod.normalReflectance = 1.5;
// _shadowMethod = new TripleFilteredShadowMapMethod(DirectionalLight(_light[0]));
_shadowMethod = new NearShadowMapMethod(new FilteredShadowMapMethod(_light[0]));
_shadowMethod.epsilon = .0007;
var material:DefaultMaterialBase;
// 0 - ground
material = materialFromBitmap('ground', [_mapList[6], _mapList[7], _mapList[8]], true)
// material = materialFromBitmap('ground', [_mapList[6]],true)
material.ambient = 1;
material.gloss = 30;
material.specular = 1;
material.repeat = true;
material.addMethod(_fog);
// 1 - Hero
material = materialFromBitmap('hero', [_mapList[0], _mapList[1], _mapList[2]])
material.gloss = 16;
material.specular = 0.6;
material.ambient = 1;
//transparency
material.alphaPremultiplied = true;
material.alphaThreshold = 0.9;
// 2 - gun
material = materialFromBitmap('gun', [_mapList[3], _mapList[4], _mapList[5]])
material.gloss = 16;
material.specular = 0.6;
material.ambient = 1;
initObjects();
}
/**
* Material from bitmap
*/
protected function materialFromBitmap(name:String, Bitmaps:Array, Spec:Boolean=false):DefaultMaterialBase {
// auto map if one bitmap
if (Bitmaps.length == 1) {
// _mapper.AutoMapper(Bitmaps[0]);
Bitmaps.push(_mapper.bitdata[1]);
Bitmaps.push(_mapper.bitdata[0]);
}
var material:TextureMaterial = new TextureMaterial(new BitmapTexture(Bitmaps[0]));
material.normalMap = new BitmapTexture(Bitmaps[1]);
material.normalMap = Cast.bitmapTexture(Bitmaps[1]);
//bodyMaterial.normalMap = Cast.bitmapTexture(BodyNormals);
if (Spec)
material.specularMap = new BitmapTexture(Bitmaps[2]);
else
material.addMethod(new LightMapMethod(new BitmapTexture(Bitmaps[2])));
material.name = name;
material.lightPicker = _lightPicker;
//material.diffuseLightSources = LightSources.PROBES;
material.specularLightSources = LightSources.LIGHTS;
material.specularMethod = _specularMethod;
material.shadowMethod = _shadowMethod;
//push to reference
_materials.push(material);
return material;
}
/**
* Initialise the scene objects
*/
private function initObjects():void {
ground = new Mesh(new PlaneGeometry(100000, 100000), _materials[0]);
ground.geometry.scaleUV(160, 160);
ground.y = -480;
ground.castsShadows = false;
_view.scene.addChild(ground);
load(referenceLink+"assets/onkba.awd");
}
//--------------------------------------------------------------------- GLOBAL LOADER
/**
* Global Load Binary file
*/
private function load(url:String):void {
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
switch (url.substring(url.length - 3)) {
case "AWD":
case "awd":
loader.addEventListener(Event.COMPLETE, parseAWD, false, 0, true);
break;
case "png":
case "jpg":
loader.addEventListener(Event.COMPLETE, parseBitmap);
break;
}
loader.addEventListener(ProgressEvent.PROGRESS, loadProgress, false, 0, true);
loader.load(new URLRequest(url));
}
/**
* Display current load
*/
private function loadProgress(e:ProgressEvent):void {
var P:int = int(e.bytesLoaded / e.bytesTotal * 100);
if (P != 100)
log('Load : ' + P + ' % | ' + int((e.bytesLoaded / 1024) << 0) + ' ko\n');
else
message();
}
//--------------------------------------------------------------------- BITMAP DISPLAY
private function parseBitmap(e:Event):void {
log("out")
var urlLoader:URLLoader = e.target as URLLoader;
var loader:Loader = new Loader();
loader.loadBytes(urlLoader.data);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBitmapComplete, false, 0, true);
urlLoader.removeEventListener(Event.COMPLETE, parseBitmap);
urlLoader.removeEventListener(ProgressEvent.PROGRESS, loadProgress);
loader = null;
}
private function onBitmapComplete(e:Event):void {
var loader:Loader = LoaderInfo(e.target).loader;
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onBitmapComplete);
_mapList.push(e.target.content.bitmapData);
loader.unload();
loader = null;
n++;
if (referenceMap[n])
load(referenceLink+'assets/' + referenceMap[n]);
else {
initMaterial();
}
}
//--------------------------------------------------------------------- AWD DISPLAY
/**
* Load AWD
*/
private function parseAWD(e:Event):void {
var loader:URLLoader = e.target as URLLoader
var loader3d:Loader3D = new Loader3D(false);
loader3d.addEventListener(AssetEvent.ASSET_COMPLETE, onAssetComplete, false, 0, true);
loader3d.addEventListener(LoaderEvent.RESOURCE_COMPLETE, finalAWD, false, 0, true);
loader3d.loadData(loader.data, null, null, new AWD2Parser());
loader.removeEventListener(ProgressEvent.PROGRESS, loadProgress);
loader.removeEventListener(Event.COMPLETE, parseAWD);
loader = null;
}
/**
* Listener function for asset complete event on loader
*/
private function onAssetComplete(event:AssetEvent):void {
var mesh:Mesh;
var material:TextureMaterial;
var specularMethod:FresnelSpecularMethod
if (event.asset.assetType == AssetType.SKELETON) {
//create a new skeleton animation set
animationSet = new SkeletonAnimationSet(3);
//wrap our skeleton animation set in an animator object and add our sequence objects
animator = new SkeletonAnimator(animationSet, event.asset as Skeleton, true);
} else if (event.asset.assetType == AssetType.ANIMATION_STATE) {
//create state objects for each animation state encountered
var animationState:SkeletonAnimationState = event.asset as SkeletonAnimationState;
animationSet.addState(animationState.name, animationState);
//if (animationState.name == ANIM_BREATHE) stop();
} else if (event.asset.assetType == AssetType.MESH) {
mesh = Mesh(event.asset)
if (mesh) {
if (mesh.name == "Onkba") {
hero = mesh;
hero.material = _materials[1];
hero.castsShadows = true;
hero.scale(10);
}
if (mesh.name == "Gun") {
gun = mesh;
gun.material = _materials[2];
gun.castsShadows = true;
gun.scale(10);
gun.z = -250;
gun.y = -470;
gun.rotationY = 0;
gun.rotationX = 0;
}
}
}
}
/**
* Check if all resourse loaded
*/
private function finalAWD(e:LoaderEvent):void {
//apply our animator to our mesh
hero.animator = animator;
//add dynamique eyes
addHeroEye(10);
//default to breathe sequence
stop();
var loader3d:Loader3D = e.target as Loader3D;
loader3d.removeEventListener(AssetEvent.ASSET_COMPLETE, onAssetComplete);
loader3d.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, finalAWD);
_view.scene.addChild(hero);
_view.scene.addChild(gun);
}
/**
* Test some Clone
*/
private function makeClone(n:int=20):void {
if (!cloneActif) {
cloneActif = true;
var g:Mesh;
var decal:int = -(n * 400) / 2;
for (var j:int = 1; j < n; j++) {
for (var i:int = 1; i < n; i++) {
g = Mesh(hero.clone());
g.x = decal + (400 * i);
g.z = (decal + (400 * j));
if (g.x != 0 || g.z != 0)
_view.scene.addChild(g);
}
}
}
}
/**
* Character breath animation
*/
private function stop():void {
isMoving = false;
//update animator speed
animator.playbackSpeed = BREATHE_SPEED;
//update animator sequence
if (currentAnim == ANIM_BREATHE)
return;
currentAnim = ANIM_BREATHE;
animator.play(currentAnim, stateTransition);
}
/**
* Character fight animation
*/
private function fight():void {
//update animator sequence
if (currentAnim == ANIM_FIGHT) {
return;
}
animator.playbackSpeed = FIGHT_SPEED;
currentAnim = ANIM_FIGHT;
animator.play(currentAnim, stateTransition);
}
/**
* Character fight animation
*/
private function fight2():void {
//update animator sequence
if (currentAnim == ANIM_BOXE) {
return;
}
animator.playbackSpeed = BOXE_SPEED;
currentAnim = ANIM_BOXE;
animator.play(currentAnim, stateTransition);
}
/**
* Character jump animation
*/
private function jump():void {
isJumping = false;
}
/**
* Character Mouvement
*/
private function updateMovement(dir:Number):void {
isMoving = true;
//update animator speed
animator.playbackSpeed = dir * (isRunning ? RUN_SPEED : WALK_SPEED);
//update animator sequence
var anim:String = isRunning ? ANIM_RUN : ANIM_WALK;
if (currentAnim == anim)
return;
currentAnim = anim;
animator.play(currentAnim, stateTransition);
}
//--------------------------------------------------------------------- KEYBORD
/**
* Key down listener for animation
*/
private function onKeyDown(event:KeyboardEvent):void {
switch (event.keyCode) {
case Keyboard.SHIFT:
isRunning = true;
if (isMoving)
updateMovement(movementDirection);
break;
case Keyboard.UP:
case Keyboard.W:
case Keyboard.Z: //fr
updateMovement(movementDirection = 1);
break;
case Keyboard.DOWN:
case Keyboard.S:
updateMovement(movementDirection = -1);
break;
case Keyboard.LEFT:
case Keyboard.A:
case Keyboard.Q: //fr
currentRotationInc = -ROTATION_SPEED;
break;
case Keyboard.RIGHT:
case Keyboard.D:
currentRotationInc = ROTATION_SPEED;
break;
case Keyboard.E:
fight2();
break;
case Keyboard.SPACE:
case Keyboard.R:
fight();
break;
case Keyboard.N:
randomSky();
break;
case Keyboard.B:
makeClone();
break;
}
}
/**
* Key up listener
*/
private function onKeyUp(event:KeyboardEvent):void {
switch (event.keyCode) {
case Keyboard.SHIFT:
isRunning = false;
if (isMoving)
updateMovement(movementDirection);
break;
case Keyboard.UP:
case Keyboard.W:
case Keyboard.Z: //fr
case Keyboard.DOWN:
case Keyboard.S:
case Keyboard.SPACE:
case Keyboard.E:
case Keyboard.R:
stop();
break;
case Keyboard.LEFT:
case Keyboard.A:
case Keyboard.Q: //fr
case Keyboard.RIGHT:
case Keyboard.D:
currentRotationInc = 0;
break;
}
}
//--------------------------------------------------------------------- NAVIGATION
/**
* stage listener and mouse control
*/
private function onResize(event:Event=null):void {
_view.width = stage.stageWidth;
_view.height = stage.stageHeight;
_stats.x = stage.stageWidth - _stats.width;
//_signature.y = stage.stageHeight - _signature.height;
}
private function onStageMouseDown(ev:MouseEvent):void {
_prevMouseX = ev.stageX;
_prevMouseY = ev.stageY;
_mouseMove = true;
}
private function onStageMouseLeave(event:Event):void {
_mouseMove = false;
}
private function onStageMouseMove(ev:MouseEvent):void {
if (_mouseMove) {
_hoverCtrl.panAngle += (ev.stageX - _prevMouseX);
_hoverCtrl.tiltAngle += (ev.stageY - _prevMouseY);
}
_prevMouseX = ev.stageX;
_prevMouseY = ev.stageY;
}
/**
* mouseWheel listener
*/
private function onStageMouseWheel(ev:MouseEvent):void {
_hoverCtrl.distance -= ev.delta * 5;
if (_hoverCtrl.distance < 600) {
if (ev.delta > 0)
_cameraHeight += 10;
else
_cameraHeight -= 10;
}
if (_hoverCtrl.distance < 100)
_hoverCtrl.distance = 100;
else if (_hoverCtrl.distance > 2000)
_hoverCtrl.distance = 2000;
}
//--------------------------------------------------------------------- EYE
/**
* Dynamique eye
*/
public function addHeroEye(Scale:Number):void {
if (_eyes)
return;
// texture
_eyeMapClose = new ColorMaterial(0xA13D1E);
_eyeMapClose.lightPicker = _lightPicker;
_eyeMapClose.specularLightSources = LightSources.LIGHTS;
_eyeMapClose.shadowMethod = new TripleFilteredShadowMapMethod(DirectionalLight(_light[0]));
_eyeMapClose.gloss = 12;
_eyeMapClose.specular = 0.6;
_eyeMapClose.ambient = 1;
_materials.push(_eyeMapClose);
//get eye texture from reference bitmap
var m:Matrix = new Matrix();
m.translate(-283/2, -197/2);
var b:BitmapData = new BitmapData(256/2, 256/2, false, 0xffffff)
b.draw(_mapList[0], m)
_eyeMapOpen = new TextureMaterial(new BitmapTexture(b));
_eyeMapOpen.lightPicker = _lightPicker;
_eyeMapOpen.specularLightSources = LightSources.LIGHTS;
_eyeMapOpen.addMethod(new EnvMapMethod(_mapper.sky, 0.1));
_eyeMapOpen.shadowMethod = new TripleFilteredShadowMapMethod(DirectionalLight(_light[0]));
_eyeMapOpen.gloss = 300;
_eyeMapOpen.specular = 5;
_eyeMapOpen.ambient = 1;
_eyeMapOpen.repeat = true;
_materials.push(_eyeMapOpen);
// object
_eyes = new Mesh(new Geometry());
_eyesTarget = new Mesh(new Geometry());
_eyeR = new Mesh(new SphereGeometry(1, 32, 24), _eyeMapClose);
_eyeL = new Mesh(new SphereGeometry(1, 32, 24), _eyeMapClose);
_eyeR.castsShadows = _eyeL.castsShadows = false;
_eyes.addChild(_eyeR);
_eyes.addChild(_eyeL);
_eyeR.geometry.scaleUV(2, 1);
_eyeL.geometry.scaleUV(2, 1);
_eyeR.z = _eyeL.z = 3.68;
_eyeR.x = _eyeL.x = 6;
_eyeR.y = 1.90;
_eyeL.y = -1.46;
_heroPieces = new Mesh(new Geometry());
_heroPieces.scale(Scale);
_heroPieces.addChild(_eyesTarget);
_heroPieces.addChild(_eyes);
_eyeLook = new Mesh(new PlaneGeometry(0.3, 0.3, 1, 1), new ColorMaterial(0xFFFFFF, 1));
_eyeLook.rotationX = 90;
_eyeLook.visible = false;
var h:ColorMaterial = new ColorMaterial(0xFFFFFF, 1)
var zone:Mesh = new Mesh(new PlaneGeometry(12, 6, 1, 1), h);
zone.castsShadows = false;
zone.material.blendMode = "multiply";
zone.addEventListener(MouseEvent3D.MOUSE_MOVE, onMeshMouseMove);
zone.addEventListener(MouseEvent3D.MOUSE_OVER, onMeshMouseOver);
zone.addEventListener(MouseEvent3D.MOUSE_OUT, onMeshMouseOut);
zone.mouseEnabled = true;
zone.rotationX = 90;
zone.rotationZ = 90;
zone.z = 10;
zone.x = 6;
zone.y = 0.22;
_eyeLook.z = 10.2;
_eyeLook.x = 6;
_eyeLook.y = 0.22;
_eyePosition = _eyeLook.position;
_eyes.addChild(zone);
_eyes.addChild(_eyeLook);
_view.scene.addChild(_heroPieces);
}
/**
* mesh listener for mouse over interaction
*/
private function onMeshMouseOver(event:MouseEvent3D):void {
event.target.showBounds = true;
_eyeLook.visible = true;
onMeshMouseMove(event);
}
/**
* mesh listener for mouse out interaction
*/
private function onMeshMouseOut(event:MouseEvent3D):void {
event.target.showBounds = false;
_eyeLook.visible = false;
_eyeLook.position = _eyePosition;
}
/**
* mesh listener for mouse move interaction
*/
private function onMeshMouseMove(event:MouseEvent3D):void {
_eyeLook.position = new Vector3D(event.localPosition.z + 6, event.localPosition.x, event.localPosition.y + 10);
}
private function updateEye():void {
if (_heroPieces && hero) {
_heroPieces.transform = hero.transform;
//get the head bone
if (animator)
if (animator.globalPose.numJointPoses >= 40) {
_eyes.transform = animator.globalPose.jointPoses[39].toMatrix3D();
_eyes.position.add(new Vector3D(-10.22, 0, 0));
}
// look
_eyeR.lookAt(_eyeLook.position.add(new Vector3D(0, 1.4, 0)), new Vector3D(0, 1, 1));
_eyeL.lookAt(_eyeLook.position.add(new Vector3D(0, -1.4, 0)), new Vector3D(0, 1, 1));
// open close eye
_eyeCount++
if (_eyeCount > 300)
closeEye();
if (_eyeCount > 309)
openEye();
}
}
private function closeEye():void {
_eyeR.material = _eyeMapClose;
_eyeL.material = _eyeMapClose;
}
private function openEye():void {
_eyeR.material = _eyeMapOpen;
_eyeL.material = _eyeMapOpen;
_eyeCount = 0;
}
//--------------------------------------------------------------------- FLASH SIDE
/**
* Create an instructions overlay
*/
private function initText():void {
_text = new TextField();
_text.defaultTextFormat = new TextFormat("Verdana", 11, 0xFFFFFF);
_text.width = 300;
_text.height = 250;
_text.selectable = false;
_text.mouseEnabled = true;
_text.wordWrap = true;
_text.filters = [new DropShadowFilter(1, 45, 0x0, 1, 0, 0)];
addChild(_text);
}
/**
* final message
*/
protected function message():void {
_text.htmlText = "<a href='http://3dflashlo.wordpress.com/' target='_blank'>ABOUT</a>";
_text.htmlText += " - <a href='https://github.com/lo-th/loth_labs' target='_blank'>SOURCE</a>\n\n";
_text.htmlText = "<a href='http://3dflashlo.wordpress.com/' target='_blank'>ABOUT</a>";
_text.htmlText += " - <a href='https://github.com/lo-th/loth_labs' target='_blank'>SOURCE</a>\n\n";
_text.appendText("Cursor keys / WSAD / ZSQD - move\n");
_text.appendText("SHIFT - hold down to run\n");
_text.appendText("E - punch\n");
_text.appendText("SPACE / R - guard\n");
_text.appendText("N - random sky\n");
_text.appendText("B - clone !\n");
}
/**
* log for display info
*/
private function log(t:String):void {
_text.htmlText = t;
}
}
}
import flash.filters.DisplacementMapFilter;
import away3d.textures.BitmapCubeTexture;
import flash.display.DisplayObject;
import flash.filters.ShaderFilter;
import flash.geom.ColorTransform;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.Shader;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
class Mapper extends Sprite {
/*[Embed(source="/../embeds/filters/sharpen.pbj",mimeType="application/octet-stream")]
private var BumpClass:Class;
[Embed(source="/../embeds/filters/NormalMap.pbj",mimeType="application/octet-stream")]
private var NormalClass:Class;
[Embed(source="/../embeds/filters/Outline.pbj",mimeType="application/octet-stream")]
private var LumaClass:Class;
*/
private var _shaders:Vector.<Shader>;
private var _bitmap:Vector.<Bitmap>;
private var _bitdata:Vector.<BitmapData>;
private var _skydata:Vector.<BitmapData>;
private var _sky:BitmapCubeTexture;
public function Mapper() {
}
//--------------------------------------------------------------------- AUTO MAP
/**
* auto mapper (normal, speculare, occlusion)
*/
/*public function AutoMapper(origineMap:BitmapData=null):void {
_shaders = new Vector.<Shader>();
_bitmap = new Vector.<Bitmap>();
_bitdata = new Vector.<BitmapData>();
_bitmap.push(new Bitmap(origineMap), new Bitmap(origineMap), new Bitmap(origineMap))
_shaders.push(new Shader(new BumpClass()), new Shader(new NormalClass()), new Shader(new LumaClass()))
applyFilters();
}*/
/**
* apply filters
*/
/* private function applyFilters():void {
// Bump
_shaders[0].data.amount.value = [20];
_shaders[0].data.radius.value = [.1];
_bitmap[0].filters = [new ShaderFilter(_shaders[0])];
// Normal
_shaders[1].data.amount.value = [10]; //0 to 5
_shaders[1].data.soft_sobel.value = [1]; //int 0 or 1
_shaders[1].data.invert_red.value = [-1]; //-1 to 1
_shaders[1].data.invert_green.value = [-1]; //-1 to 1
_bitmap[1].filters = [new ShaderFilter(_shaders[1])];
// Speculare
_shaders[2].data.difference.value = [1, 0.5];
_shaders[2].data.color.value = [1, 1, 1, 1];
_shaders[2].data.bgcolor.value = [0, 0, 0, 1];
_bitmap[2].filters = [new ShaderFilter(_shaders[2])];
_bitdata.push(bit(_bitmap[0]), bit(_bitmap[1]), bit(_bitmap[2]))
}*/
/**
* get bitmapData
*/
private function bit(B:Bitmap):BitmapData {
var b:BitmapData = new BitmapData(B.width, B.height, true);
b.draw(B);
return b;
}
/**
* return map
*/
public function get bitdata():Vector.<BitmapData> {
return _bitdata;
}
//--------------------------------------------------------------------- VECTOR SKY
/**
* create vector sky
*/
public function vectorSky(COLOR:Array, quality:uint=8):void {
var xl:uint = 128 * quality;
var pinch:uint = xl / 3.6;
// sky color from bottom to top;
var color:Array = [brighten(COLOR[0], 50), darken(COLOR[0], 25), darken(COLOR[0], 5), darken(COLOR[1], 0), COLOR[1], COLOR[2], darken(COLOR[2], 25), darken(COLOR[2], 50)]; // clear
var side:BitmapData = new BitmapData(xl, xl, false, color[1]);
var top:BitmapData = new BitmapData(xl, xl, false, color[6]);
var floor:BitmapData = new BitmapData(xl, xl, false, color[1]);
// side
var matrix:Matrix = new Matrix();
matrix.createGradientBox(xl, xl, -Math.PI / 2)
var g:Sprite = new Sprite();
g.graphics.beginGradientFill('linear', [color[1], color[2], color[3], color[4], color[5], color[6]], [1, 1, 1, 1, 1, 1], [90, 110, 120, 126, 180, 230], matrix);
g.graphics.drawRect(0, 0, xl, xl);
g.graphics.endFill();
var displacement_map:DisplacementMapFilter = new DisplacementMapFilter(pinchMap(xl, xl), new Point(0, 0), 4, 2, 0, pinch, "clamp")
g.filters = [displacement_map];
//g.addChild(_bitmap[2])
side.draw(g);
// top
g = new Sprite;
matrix = new Matrix();
matrix.createGradientBox(xl, xl, 0, 0, 0);
g.graphics.beginGradientFill('radial', [color[7], color[6]], [1, 1], [0, 255], matrix);
g.graphics.drawEllipse(0, 0, xl, xl);
g.graphics.endFill();
top.draw(g);
// bottom
g = new Sprite;
matrix = new Matrix();
matrix.createGradientBox(xl, xl, 0, 0, 0);
g.graphics.beginGradientFill('radial', [color[0], color[1]], [1, 1], [0, 255], matrix);
g.graphics.drawEllipse(0, 0, xl, xl);
g.graphics.endFill();
floor.draw(g);
_skydata = new Vector.<BitmapData>();
_skydata.push(side, top, floor);
if (_sky)
_sky.dispose();
_sky = new BitmapCubeTexture(side, side, top, floor, side, side);
}
/**
* add sphericale distortion
*/
private function pinchMap(w:int, h:int):BitmapData {
var b:BitmapData = new BitmapData(w, h, false, 0x000000)
var vx:int = w >> 1;
var vy:int = h >> 1;
for (var j:int = 0; j < h; j++) {
for (var i:int = 0; i < w; i++) {
var BCol:Number = 127 + (i - vx) / (vx) * 127 * (1 - Math.pow((j - vy) / (vy), 2))
var GCol:Number = 127 + (j - vy) / (vy) * 127 * (1 - Math.pow((i - vx) / (vx), 2))
b.setPixel(i, j, (GCol << 8) | BCol)
}
}
return b
}
/**
* sky reference
*/
public function get sky():BitmapCubeTexture {
return _sky;
}
//--------------------------------------------------------------------- COLORS UTILS
/**
* brighten color
*/
public function brighten(hexColor:Number, percent:Number):Number {
if (isNaN(percent))
percent = 0;
if (percent > 100)
percent = 100;
if (percent < 0)
percent = 0;
var factor:Number = percent / 100, rgb:Object = hexToRgb(hexColor);
rgb.r += (255 - rgb.r) * factor;
rgb.b += (255 - rgb.b) * factor;
rgb.g += (255 - rgb.g) * factor;
return rgbToHex(Math.round(rgb.r), Math.round(rgb.g), Math.round(rgb.b));
}
/**
* darken color
*/
public function darken(hexColor:Number, percent:Number):Number {
if (isNaN(percent))
percent = 0;
if (percent > 100)
percent = 100;
if (percent < 0)
percent = 0;
var factor:Number = 1 - (percent / 100), rgb:Object = hexToRgb(hexColor);
rgb.r *= factor;
rgb.b *= factor;
rgb.g *= factor;
return rgbToHex(Math.round(rgb.r), Math.round(rgb.g), Math.round(rgb.b));
}
/**
* conversion
*/
public function rgbToHex(r:Number, g:Number, b:Number):Number {
return (r << 16 | g << 8 | b);
}
public function hexToRgb(hex:Number):Object {
return {r: (hex & 0xff0000) >> 16, g: (hex & 0x00ff00) >> 8, b: hex & 0x0000ff};
}
/**
* apply color to object
*/
public function color(o:DisplayObject, c:int=0, a:Number=1):void {
if (o) {
var nc:ColorTransform = o.transform.colorTransform
nc.color = c;
nc.alphaMultiplier = a;
if (c == 0)
o.transform.colorTransform = new ColorTransform()
else
o.transform.colorTransform = nc
}
}
//--------------------------------------------------------------------- MATH UTILS
/**
* random generator
*/
private function Ran(max:Number=1, min:Number=0):Number {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}