TWaver MONO Design

  1. MONO Design
  2. DataBox与Network

使用DataBox

DataBox是管理所有数据对象的容器,在MVC框架中处于M(模型)层,它是视图的数据提供者,它的主要功能是对数据进行装载、卸载,并对数据元素的变化进行监听。

数据操作

DataBox中的数据可以通过API创建,也可以通过XML或JSON的方式进行序列化和反序列化。DataBox中提供了许多对数据操作的API,以下列出了常用的API:

  • add(data, index) 往数据容器中添加一个数据
  • addByDescendant(data) 如果节点有孩子,就把节点的孩子也添加到数据容器中
  • remove(data) 从数据容器中删除某个数据
  • removeById(id) 通过数据的ID编号从数据容器中删除该数据
  • contains(data) 判断是否包含某个数据
  • containsById(id) 通过数据ID判断是否包含某个数据
  • getDataById(id) 根据数据的ID编号获取对应的数据
  • getDatas() 获取数据容器中的所有数据
  • getDataAt(index) 获取数据容器中某个序号上的数据
  • size() 数据容器的大小,也就是容器中数据的数量
  • lightsSize() 数据容器中光源的数量
  • getLights() 获取数据容器中所有的光源
  • clear() 清空数据容器中所有的数据
  • removeSelection 删除所有选中的数据
  • clearSelection 对所有数据取消选中
  • clearEditing 对所有数据取消编辑

以下一段程序展示了对Databox中数据的增删改查:

var box = new mono.DataBox();
for(var i = 0; i < 3; i++) {
    var element = new mono.Element("element_" + i);
    element.setName("element_" + i);
    box.add(element);
}
box.forEach(function(element) {
    console.log(element.getName()); //element_0,element_1,element_2
});
var element0 = box.getDataAt(0);
element0.setName("newElement");
console.log(element0.getName());//newElement
box.remove(element0);
console.log(box.size());//3
box.clear();
console.log(box.size());//0

如果想要呈现优美的3D场景,还需要DataBox和Network(视图层)关联,通过模型驱动视图来展现3D场景:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>Cube</title>
  <script type="text/javascript" src = "mono.js"></script>
  <script type="text/javascript">
    function init(){
      var box = new mono.DataBox();
      var camera = new mono.PerspectiveCamera(30, 1.5, 0.1, 10000);
      camera.setPosition(-800,800,-800);
      camera.look(new mono.Vec3(0, 0, 0));

      var network= new mono.Network3D(box, camera, myCanvas);
      var interaction2 = new mono.SelectionInteraction(network);
      var interaction=new mono.DefaultInteraction(network);
      interaction.zoomSpeed=5;
      var interactions = [interaction, interaction2];
      network.setInteractions(interactions);
      mono.Utils.autoAdjustNetworkBounds(network,document.documentElement,'clientWidth','clientHeight');

      var cube = new mono.Cube(200,200,200);
      cube.setStyle('m.type','basic');
      cube.setStyle('m.color', "green");
      cube.setPosition(0,0,0);
      box.add(cube);
   }
  </script>
</head>
<body onload = "init()">
<div id = "mainDiv"><canvas id="myCanvas" /></div>
</body>
</html>

运行效果图:
cube

事件监听

DataBox可以对容器中的数据对象的变化进行监听,DataBox提供了以下的事件监听器供用户使用:

  • addDataBoxChangeListener(listener, scope, ahead) 当数据容器中的数据发生改变时(增加,删除,清空),就可以通过此方法监听
  • removeDataBoxChangeListener(listener, scope) 移除数据容器的数据增减变化的监听器
  • addDataPropertyChangeListener(listener,scope,ahead) 当数据容器中的数据属性发生变化时,比如网元位置,网元名称等,都可以通过此方法来监听
  • removeDataPropertyChangeListener(listener, scope) 移除数据容器中数据的属性更改事件的监听器

以下一段程序展示了监听器的使用:

var box = new mono.DataBox();
var element = new mono.Element();
box.addDataBoxChangeListener(function (e) {
  console.log(e.kind); // "add","remove"
});
var element2 = new mono.Element();
box.add(element2);
box.remove(element);

使用Network组件

Network3D是一个用于交互的视图组件,可以展示3D场景,并实现用户和3D场景之间的交互,比如旋转镜头,选中3D对象,通过鼠标或键盘移动3D对象等。

在网页中添加Network

在网页中插入Network3D,首先自定义一个div,并创建一张画布canvas:

<div id = "mainDiv" >
    <canvas id="myCanvas" width="800" height="800"/>
</div>

Network3D需要由一个与之关联的DataBox驱动,显示DataBox中的网元。当初始化Network3D时,DataBox默认会绑定在Network3D上。通过network3D构造方法创建network3D,并与DataBox、Camera和canvas绑定:

//构造方法
Network3D=function(dataBox,camera,canvas,parameters){}; 

下面的例子在html中创建了一个network3D,并展现出一个3D物体。

<!DOCTYPE html>
<html>
<head>
<title>Room Inspection</title>
<script type="text/javascript" src = "libs/mono.js"></script>
<script type="text/javascript" src = "libs/twaver.js"></script>
<script type="text/javascript">
var network, interaction;
function load(){
    var box = new mono.DataBox();
    var camera = new mono.PerspectiveCamera(30, 1.5, 0.1, 10000);
    var target = new mono.Vec3(150,50,150); 
    camera.setPosition(1000,500,1000);
    camera.lookAt(target);
    network = new mono.Network3D(box, camera, myCanvas);
    mono.Utils.autoAdjustNetworkBounds(network,document.documentElement,'clientWidth','clientHeight');    
    box.add(new mono.AmbientLight(0xffffff));           
    createBall(box);
}
function createBall(box){
    var ball=new mono.Sphere(300,100);			 
    ball.setStyle('m.texture.image','images/earth2.png');
    ball.setStyle('m.type','phong');						
    ball.setStyle('m.texture.repeat',new mono.Vec2(1,1));	  
    ball.setStyle('m.specularStrength',100);		
    box.add(ball);
}
    </script>
</head>
<body onload = 'load()'>
    <div id = "mainDiv" >
        <canvas id="myCanvas" width="800" height="800"/>
    </div>
</body>
</html>

执行代码后运行效果如图。
77

Interaction交互模式

mono中提供了DefaultInteraction、SelectIonInteraction、EditInteraction等三种交互模式。DefaultInteraction交互模式包括可以在3D场景中旋转镜头,通过鼠标滚轮缩放镜头,键盘操作镜头等。设置SelectionInteraction交互模式,3D场景中的对象可以被选中,也可以按住ctrl键进行框选;在EditInteraction模式下可以编辑3D对象,例如平移,缩放,旋转等。
也可以通过setInteractions方法为network同时设置多种交互模式。

  • DefaultInteraction.getRotateSpeed():获取镜头旋转的速度
  • DefaultInteraction.setRotateSpeed(rotateSpeed):设置镜头旋转的速度
  • DefaultInteraction.getZoomSpeed():获取镜头缩放的速度
  • DefaultInteraction.setZoomSpeed(zoomSpeed):设置镜头缩放的速度
  • DefaultInteraction.getPanSpeed():获取镜头平移的速度
  • DefaultInteraction.setPanSpeed(panSpeed)设置镜头平移的速度
  • EditInteraction.setShowHelpers(showHelpers):设置是否显示帮助的组件
  • EditInteraction.setScaleable(scaleable):设置是否可缩放
  • EditInteraction.setRotateable(rotateable):设置是否可旋转
  • EditInteraction.setTranslateable(translateable):设置是否可平移
  • EditInteraction.setDefaultMode(defaultMode):设置默认的模式,mono中提供了三种模式:translate,rotate和scale
  • EditInteraction.setScaleRate(scaleRate):设置缩放率
  • EditInteraction.setForceSameScale(forceSameScale):设置是否需要等比例缩放

下面代码为network设置了DefaultInteraction和SelectionInteraction两种交互模式。

network= new mono.Network3D(box, camera, myCanvas);
interaction = new MONO.DefaultInteraction(network);
interaction.zoomSpeed = 30;
interaction.yLowerLimitAngle = Math.PI/180;
interaction.yUpLimitAngle = Math.PI / 3;
network.setInteractions([new MONO.SelectionInteraction(network), interaction]);

自适应缩放

自适应缩放会自动调整Network3D的Bounds值,使3D物体在network中的呈现更加友善。可通过如下方法实现:

autoAdjustNetworkBounds = function(network, o, w, h, left, top) {}

鼠标键盘交互事件

mono中为我们提供了非常友善的用户鼠标键盘交互事件,下面列出常用的事件。

    鼠标交互事件

  • 按住左键移动:旋转物体
  • 按住右键移动:平移物体
  • 滚轴:缩放物体
    键盘交互事件

  • pageup:沿着z轴正方向移动
  • pagedown:沿着z轴负方向移动
  • left:沿着x轴正方向移动
  • up:沿着x轴负方向移动
  • right:沿着y轴正方向移动
  • down:沿着y轴负方向移动
  • ctrl+A:全选
  • ctrl+C:复制
  • ctrl+V:粘贴

自动渲染

我们可以通过setRenderSelectFunction()方法过滤哪些选中的网元需要绘制选择边框,哪些不需要绘制边框。

setRenderSelectFunction = function(f) {}

我们还可以在分别监听到渲染前后,使用setBeforeRenderFunction()设置渲染Network3D前的执行方法,使用setRenderCallback()来设置渲染Network3D之后的回调方法。方法原型如下:

mono.Network3D.prototype.setRenderCallback = function(f) {}
//调用setRenderCallback方法
network.setRenderCallback(function(){
    //do something
});

mono.Network3D.prototype.setBeforeRenderFunction = function(f) {}
//调用setBeforeRenderFunction方法
network.setBeforeRenderFunction(function(){
//do something
});