使用Away3d实现模型的粒子化
<img src="http://www.everyinch.net/wp-content/uploads/2014/07/away3d_particles/ParticleModel.jpg" width="550" height="587" class="alignnone" />项目源文件下载
[code lang="as3"]
package {
import away3d.animators.*;
import away3d.animators.data.*;
import away3d.animators.nodes.*;
import away3d.containers.*;
import away3d.controllers.*;
import away3d.core.base.*;
import away3d.debug.*;
import away3d.entities.*;
import away3d.events.AssetEvent;
import away3d.library.assets.AssetType;
import away3d.lights.PointLight;
import away3d.loaders.Loader3D;
import away3d.loaders.misc.AssetLoaderContext;
import away3d.loaders.parsers.AWD2Parser;
import away3d.loaders.parsers.Parsers;
import away3d.materials.*;
import away3d.materials.lightpickers.StaticLightPicker;
import away3d.primitives.*;
import away3d.textures.BitmapTexture;
import away3d.tools.helpers.*;
import away3d.utils.*;
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.utils.Timer;
[SWF(backgroundColor="#000000", frameRate="60")]
public class Away3d_Particles4 extends Sprite{
[Embed(source="House/head.awd",mimeType="application/octet-stream")]
public static var HouseModel:Class;
[Embed(source="House/head_diffuse.jpg")]
public static var HouseTexture:Class;
private var view:View3D;
private var cameraController:HoverController;
private var data:Vector.<Vector3D>;
private const SIZE:int = 2;
private const TIME:int = 10000;
private var state:int;
private var mesh:Mesh;
private var light:PointLight;
private var lightPicker:StaticLightPicker;
private var particleAnimator:ParticleAnimator
private var move:Boolean = false;
private var lastPanAngle:Number;
private var lastTiltAngle:Number;
private var lastMouseX:Number;
private var lastMouseY:Number;
private var angle:Number = 0;
public function Away3d_Particles4(){
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
view = new View3D();
addChild(view);
cameraController = new HoverController(view.camera, null, 45, 20, 1000,5);
addChild(new AwayStats(view));
initLights();
loadModel();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.addEventListener(Event.RESIZE, onResize);
onResize();
}
private function loadModel():void{
Parsers.enableAllBundled();
var loader:Loader3D = new Loader3D();
var assetLoaderContext:AssetLoaderContext = new AssetLoaderContext();
assetLoaderContext.mapUrlToData("nullg0.jpg",new HouseTexture());
loader.x = 0;
loader.y = 0;
loader.z = 0;
loader.rotationY = 0;
loader.scale(1);
loader.addEventListener(AssetEvent.ASSET_COMPLETE,onAssetComplete(name));
loader.loadData(new HouseModel(),assetLoaderContext,null,new AWD2Parser());
//view.scene.addChild(loader);
}
private function onAssetComplete(materialName:String):Function{
var func:Function = function(e:AssetEvent):void{
if(e.asset.assetType == AssetType.MESH){
mesh = e.asset as Mesh;
//mesh.mouseEnabled = true;
initTextData();
initParticles();
var timer:Timer = new Timer(TIME);
timer.addEventListener(TimerEvent.TIMER,onTimer);
timer.start();
onTimer(null);
}
else if(e.asset.assetType == AssetType.MATERIAL){
var _material:TextureMaterial = e.asset as TextureMaterial;
_material.texture = new BitmapTexture(new HouseTexture().bitmapData);
_material.lightPicker = lightPicker;
_material.gloss = 185;
_material.specular = 0.2;
}
}
return func;
}
private function onTimer(e:Event):void{
switch (state){
case 0:
particleAnimator.playbackSpeed = 0;
particleAnimator.resetTime(0);
break;
case 1:
particleAnimator.playbackSpeed = 1;
break;
case 2:
particleAnimator.playbackSpeed = -1;
break;
}
state++;
state %= 3;
}
private function initTextData():void{
data = new Vector.<Vector3D>;
var vertices:Vector.<Number> = mesh.geometry.subGeometries[0].vertexPositionData;
for(var i:int = 0;i < vertices.length;i+=3){
var point:Vector3D = new Vector3D(vertices[i],vertices[i+1],vertices[i+2]);
point.scaleBy(1);
data.push(point);
}
}
private function initLights():void{
light = new PointLight();
light.color = 0xffffff;
light.radius = 100;
light.ambient = 0.6;
light.specular = 2;
view.scene.addChild(light);
lightPicker = new StaticLightPicker([light]);
}
private function initParticles():void{
var cube:Geometry = new CubeGeometry(SIZE,SIZE,SIZE);
var geometrySet:Vector.<Geometry> = new Vector.<Geometry>();
for (var i:int = 0; i < data.length; i++){
geometrySet.push(cube);
}
var particleGeometry:Geometry = ParticleGeometryHelper.generateGeometry(geometrySet);
var particleAnimationSet:ParticleAnimationSet = new ParticleAnimationSet();
particleAnimationSet.addAnimation(new ParticlePositionNode(ParticlePropertiesMode.LOCAL_STATIC));
particleAnimationSet.addAnimation(new ParticleVelocityNode(ParticlePropertiesMode.LOCAL_STATIC));
particleAnimationSet.initParticleFunc = initParticleFunc;
var material:ColorMaterial = new ColorMaterial(0xffffff);
material.alphaPremultiplied = true;
material.lightPicker = lightPicker;
var particleMesh:Mesh = new Mesh(particleGeometry, material);
particleAnimator = new ParticleAnimator(particleAnimationSet);
particleMesh.animator = particleAnimator;
particleAnimator.start();
view.scene.addChild(particleMesh);
}
private function initParticleFunc(prop:ParticleProperties):void{
prop.startTime = 0;
var degree1:Number = Math.random() * Math.PI * 2;
var degree2:Number = Math.random() * Math.PI * 2;
var r:Number = 15;
//设置速度
prop[ParticleVelocityNode.VELOCITY_VECTOR3D] = new Vector3D(r * Math.sin(degree1) * Math.cos(degree2), r * Math.cos(degree1) * Math.cos(degree2), r * Math.sin(degree2));
//设置位置
prop[ParticlePositionNode.POSITION_VECTOR3D] = data[prop.index];
}
private function onEnterFrame(event:Event):void{
if (move){
cameraController.panAngle = 0.3*(stage.mouseX - lastMouseX) + lastPanAngle;
cameraController.tiltAngle = 0.3*(stage.mouseY - lastMouseY) + lastTiltAngle;
}
view.render();
}
private function onMouseDown(event:MouseEvent):void{
lastPanAngle = cameraController.panAngle;
lastTiltAngle = cameraController.tiltAngle;
lastMouseX = stage.mouseX;
lastMouseY = stage.mouseY;
move = true;
stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
}
private function onMouseUp(event:MouseEvent):void{
move = false;
stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
}
private function onStageMouseLeave(event:Event):void{
move = false;
stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
}
private function onResize(event:Event = null):void{
view.width = stage.stageWidth;
view.height = stage.stageHeight;
}
}
}
[/code]