一个不错的3D引擎Sea3D

  • 内容
  • 评论
  • 相关

前几天心血来潮,研究了一下3d项目,有个朋友就给我推荐了sea3d,我试了一下还真不错,他有二种开发方式,一种是flash的away3d,一种three.js,简单的说他就是在away3d和three.js基础上做了2次开发。资源文件是在3dmax上装了一个插件,可以导出后缀名为sea的文件提供加载。
sea3d下载地址:https://github.com/sunag/sea3d

先贴demo,我先做了flash的版本,下面是地址,由于这个模型没有骨骼和动画,所以不会动(可以移动鼠标来控制镜头),换掉资源文件就可以动了。模型加载有点慢,可能需要等一会。
http://www.ajexoop.com/demo/3dDemo/Sea3DModelMananger.html

下面讲下做法,flash3d项目的通用修改参数是这样,首先再flash builder插入附加参数-swf-version=13

QQ图片20160414161135

然后在index.template.html文件的第48行加入 params.wmode = "direct";

这样就可以运行3d项目了,然后倒入away3d与sea3d的类

QQ图片20160414161445

准备工作完成,下面就是写代码了,我来贴一下代码,

 

package
{
	import away3d.animators.SkeletonAnimationSet;
	import away3d.animators.SkeletonAnimator;
	import away3d.animators.states.AnimationStateBase;
	import away3d.animators.transitions.CrossfadeTransition;
	import away3d.containers.View3D;
	import away3d.debug.AwayStats;
	import away3d.entities.JointObject;
	import away3d.entities.Mesh;
	import away3d.events.AnimationStateEvent;
 
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	import flash.net.URLRequest;
	import flash.ui.Keyboard;
 
	import sunag.events.SEAEvent;
	import sunag.sea3d.SEA3D;
	import sunag.sea3d.config.DefaultConfig;
	import sunag.utils.TimeStep;
 
	[SWF(backgroundColor="0x2f3032", frameRate="60")]
	public class Sea3DModelMananger extends Sprite
	{
		private var view:View3D;
		private var sea3d:SEA3D;		
		private var keyState:Array = [];
		private var timeStep:TimeStep = new TimeStep(stage.frameRate);
 
		private var player:Mesh;
		private var animator:SkeletonAnimator;
 
 
		protected var position:Vector3D;
 
		private var roX:Number = 0;
		private var roY:Number = 0;
		private var len:Number = 0;
 
		private var modelItem:Mesh;
 
		public function Sea3DModelMananger()
		{
			/**
			 * Basic config.
			 * */
 
			stage.stageFocusRect = false;
			stage.showDefaultContextMenu=false;	
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			catalogue = Sea3DModelMananger.getCatalogue(stage.loaderInfo.url);
 
			view = new View3D();			
			view.backgroundColor = stage.color;
			view.antiAlias = 4;
			addChild(view);
			addChild(new AwayStats(view));
 
			/**
			 * Config
			 * */			
 
			var config:DefaultConfig = new DefaultConfig();
 
			/**
			 * use cpu
			 * */
 
			//config.forceSkeletonCPU = true;
 
			/**
			 * <sea3d.container> contains all elements loaded.
			 * add objects in scene container
			 * */
 
			config.container = view.scene;
 
			/**
			 * Init loader
			 * */			
 
			sea3d = new SEA3D(config);
 
			sea3d.addEventListener(SEAEvent.COMPLETE, onComplete);			
			sea3d.load(new URLRequest(Sea3DModelMananger.sourceTransition(".../ceshi08.sea")));	
 
			/**
			 * Interactive
			 * */
 
			stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler);
			stage.addEventListener(MouseEvent.MOUSE_WHEEL,mouseWheelHandler);
 
		}
 
		private function onEnterFrame(e:Event):void
		{
			view.render();
		}
 
 
		private function onComplete(e:SEAEvent):void
		{		
			player = sea3d.getMesh("Player");
			animator = player.animator as SkeletonAnimator;
 
			position = player.position;
 
 
//			modelItem = sea3d.getMesh("wuqi");
//			
//			animator.play("run");
 
			/**
			 * <Camera001> Camera contained in MAX file.
			 * <sea3d.get...> Using for get element.		
			 * */						
 
			view.camera = sea3d.getCamera("Camera001");
			view.camera.x = 0;
			view.camera.y = 0;
			view.camera.rotationX = 0;
			view.camera.rotationY = 0;
 
			/**
			 * Start render and update.
			 * */
			len = view.camera.z;
 
			stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		private var _currentPoint:Point = new Point();
		private function mouseDownHandler(e:MouseEvent):void
		{
			_currentPoint.x = stage.mouseX;
			_currentPoint.y = stage.mouseY;
			this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
		}
 
		private function mouseUpHandler(e:MouseEvent):void
		{
			this.removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
		}
 
		private function mouseWheelHandler(e:MouseEvent):void
		{
			if(e.delta > 0)
			{
				len += 20;
			}
			else
			{
				len -= 20;
			}
			if(len > 0) len = 0;
			changeModelHandler();
		}
 
		private function enterFrameHandler(e:Event):void
		{
			var addX:Number = _currentPoint.x - stage.mouseX;
			var addY:Number = _currentPoint.y - stage.mouseY;
			_currentPoint.x = stage.mouseX;
			_currentPoint.y = stage.mouseY;
 
			roY = roY + addX;
			roX = roX + addY;
			if(roX > 90)
			{
				roX = 90;
			}
			else if(roX < -90)
			{
				roX = -90;
			}
			changeModelHandler();
 
 
		}
		protected function changeModelHandler():void
		{
			var sin_rox:Number = Math.sin(Math.PI/180*(roX))
			var cos_rox:Number = Math.cos(Math.PI/180*(roX))
 
			var yy:Number = sin_rox * len;
			var zz:Number = cos_rox * len;
 
			view.camera.x =  Math.sin(Math.PI/180*(-roY)) * zz;
			view.camera.y = yy;
			view.camera.z = Math.cos(Math.PI/180*(-roY)) * zz;
 
			view.camera.rotationX = -roX;
			view.camera.rotationY = -roY;
		}
 
		/**
		 * 获取根目录地址
		 * @param source 地址
		 * @return 目录地址
		 * 
		 */		
		public static function getCatalogue(source:String):String
		{
			if(!source) return source;
			var str:String = source.split("?")[0];
			var index:int = str.lastIndexOf("\\"); 
			if(index == -1)
			{
				index = str.lastIndexOf("/"); 
			}
			var contents:String = str.substring(0,index);
			return contents;
		}
		/**
		 * 地址转换 加上“.../”后会对地址加上目录
		 * @param source 地址
		 * @return 转化后的地址
		 * 
		 */	
		protected static var catalogue:String;
		public static function sourceTransition(source:String):String
		{
			return source.replace("...",catalogue);
		}
	}
}

不知道away3d 或者说 sea3d有没有直接控制镜头跟随模型的类(现在国内外资料都不多),我直接自己写了个算法,好久没写算法,这算法也是写得我头疼。
demo的下载地址:http://pan.baidu.com/s/1o7G6QDk

之后我会放出js版的,可以用移动端看哦!

评论

1条评论
  1. Gravatar 头像

    匿名 回复

    校长,我们来膜拜,

发表评论

电子邮件地址不会被公开。