一个不错的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版的,可以用移动端看哦!


上一篇 下一篇