这篇我们接着来看一下DrawEntityActor类,我们来看看这个继承DrawActor的类到底做了什么事。我们之前学习了Drawable对应的DrawActor,那么我们类比的来看DrawableEntity对应DrawEntityActor,这样就好理解一些。首先我们还是先来看DrawEntityActor的构造函数,看看他除了继承DrawActor以外还有哪些私有成员。下面是DrawEntityActor的构造函数。

 /*
绘制对象角色
*/
let DrawActor = require('./DrawActor');
let Geometry = require('../core/Geometry');
let StateSet = require('../core/StateSet');
let RenderEntity = require('../scene/RenderEntity');
let SceneRoot = require('../scene/SceneRoot');
let BoundingBox = require('../util/BoundingBox'); let DrawEntityActor = function (renderer) {
DrawActor.call(this, renderer); this._currentRenderEntity = undefined;//当前处理的渲染实体,临时数据
this._currentMaterial = undefined;//当前默认颜色状态,临时数据
this._isEntityMaterial = false;//临时数据,实体的材质无脑取最上面的节点
this._currentBoundingBox = new BoundingBox();//计算RenderEntity包围盒,临时数据
}; DrawEntityActor.prototype = Object.create(DrawActor.prototype);
DrawEntityActor.prototype.constructor = DrawEntityActor;

我们首先看到这个构造函数是需要renderer渲染对象作为参数的,其次他是继承DrawActor类的。他的私有成员有四个,分别是this._currentRenderEntity当前处理的渲染实体;this._currentMaterial当前默认颜色状态;this._isEntityMaterial当这个标记为false时实体的材质取最上面节点的材质;this._currentBoundingBox渲染实体的包围盒。

  就这些,其他只要是DrawActor父类原型链上包含的成员属性DrawEntityActor一概包含。   我们来看一下DrawEntityActor的成员函数有哪些,即他独有的操作是什么。我们还是老样子,一个一个来看。

 //重载
pushStateSet: function (stateset) {
if (stateset) {
if (this._isEntityMaterial) {
if (stateset.isMaterialAttribute()) {
if (this._currentMaterial === undefined) {
this._currentMaterial = stateset;//无脑取最上面的,实体的颜色状态是这样
}
} else {
//添加StateGraph子节点,更新当前活动的StateGraph为新的状态
this._currentStateBin = this._currentStateBin.addStateSetChild(stateset);
}
}
else {
//添加StateGraph子节点,更新当前活动的StateGraph为新的状态
this._currentStateBin = this._currentStateBin.addStateSetChild(stateset);
}
}
},

这个是覆盖了父类原型链上的pushStateSet函数,我们很容易可以看到这是修改了当前渲染状态树this._currentStateBin上当前渲染实体对应的状态StateSet节点的状态,其中讨巧的是如果当前状态为空,就取上级的渲染状态StateSet。剩下的就是将参数StateSet状态赋值给当前渲染实体对应的状态树上的状态节点。

  我们接下去看下一个成员函数。

 popStateSet: function (stateset) {//重载
if (stateset) {
if(this._isEntityMaterial){
if (stateset.isMaterialAttribute()) {//几何级别是最底层,这时才能置空
if (this._currentMaterial === stateset) {
this._currentMaterial = undefined;
}
} else {
this._currentStateBin = this._currentStateBin.getParent();
}
}else{
this._currentStateBin = this._currentStateBin.getParent();
}
}
},

此函数同样是重构原型链上的popStateSet函数,我们很容易可以看出来这个函数是将特定状态节点删除。这里有一个要特别注意,由于某些继承上一级状态的节点的状态和上级的状态是相同的,所以必须遍历到最靠近叶子的节点才能安全删除。
  好,我们接下去看下一个函数。

 pushDrawable: function (geometry) {//重载
let drawable = this.createDrawable();
drawable.setStateBin(this._currentStateBin);
drawable.setGeometry(geometry, this.getCurrentTransformMatrix());
drawable.setRenderEntity(this._currentRenderEntity);
if (this._currentMaterial) {
drawable.setMaterial(this._currentMaterial);
} else {//如果没有材质,提供一个默认值,非常重要,可以确保不用频繁的重新加载上级Program
drawable.setMaterial(StateSet.DefaultMaterial);
} this._currentBoundingBox.expandByBoundingBox(drawable.getBoundingBox());
this.addDrawable(drawable);
},

这个函数就包含很多操作了,同样是重构,所有的操作都是组装渲染对象drawable。首先组装状态树,接下来组装geometry几何体对象,然后装配renderEntity渲染对象,接下来设置材质material,然后设置包围盒,最后加入可绘制对象drawable。装配完成。接下去鲫鱼还有介绍几个函数。

 /*
提前遍历RenderEntity的目的
确认每个drawable的世界坐标变换,确认除RenderEntity外的状态树
相机树基本不用考虑,只有主相机
*/
DrawEntityActor.prototype[SceneRoot.typeID] = function (root) {
DrawActor.prototype[SceneRoot.typeID].call(this, root); //更新根节点的包围球
this._sceneRoot.getBoundingSphere().expandByBoundingBox(this._sceneRoot.getBoundingBox());
};
//RenderEntity
DrawEntityActor.prototype[RenderEntity.typeID] = function (Rentity) {
this._currentStateBin = this._baseState;
this._currentRenderEntity = Rentity;
this._currentMaterial = undefined;
this._isEntityMaterial = true; //这里RenderEntity的状态不考虑,RenderEntity的状态在实时渲染时起作用
this.traverse(Rentity); this._isEntityMaterial = false; //直接求得包围盒
let bb = new BoundingBox();
bb.copy(this._currentBoundingBox);
Rentity.setBoundingBox(bb);
this._sceneRoot.getBoundingBox().expandByBoundingBox(Rentity.getBoundingBox());//扩充包围盒 //重置引用,为下次使用准备
this._currentRenderEntity = undefined;
this._currentMaterial = undefined;
this._currentBoundingBox.reset();
};
//Geometry已经是叶子,不需要继续递归了
DrawEntityActor.prototype[Geometry.typeID] = function (geometry) {
let stateset = geometry.getStateSet();
this.pushStateSet(stateset, true);
this.pushDrawable(geometry);
this.popStateSet(stateset);
};
module.exports = DrawEntityActor;

这些是一些工具函数,但都挂在原型上,可见将来都可以用到。好了,今天的DrawEntityActor类就介绍完了,鲫鱼谢谢大家陪伴,下周再见。
  本文系原创,如需引用,请注明出处:https://www.cnblogs.com/ccentry/p/10261979.html

WebGL——osg框架学习四的更多相关文章

  1. WebGL——osg框架学习一

    从今天开始,我们开始正式的学习osg框架,今天我们学习的是osg的渲染模块,我们来看一下代码结构. 所有DrawXXX的js模块都是渲染的模块,我们逐一来简单介绍一下,第一个Drawable.js,这 ...

  2. WebGL——osg框架学习三

    今天继续来Draw绘制的osg模块的学习,昨天我们学习的是StateBin渲染状态树节点类,今天我们来继续学习下一个Draw的基础类DrawableEntity渲染对象实体类.这个类和Drawable ...

  3. spring框架学习(四)——注解方式AOP

    注解配置业务类 使用@Component("s") 注解ProductService 类 package com.how2java.service; import org.spri ...

  4. Android 学习笔记之AndBase框架学习(四) 使用封装好的函数实现单,多线程任务

    PS:Force Is Meaningless Without Skill 学习内容: 1.使用AndBase实现单线程任务... 2.使用AndBase实现多线程任务...   AndBase内部封 ...

  5. Jersey RESTful WebService框架学习(四)使用@FormParam

    前端 <form action="/Jersey/api/1.0/my/form" method="post"> <input type=&q ...

  6. Hibernate框架学习(四)——事务

    一.回顾事务的概念http://www.cnblogs.com/cxq1126/p/8313600.html 1.特性ACID:原子性.一致性.隔离性.持久性 2.并发问题:脏读.不可重复读.幻|虚读 ...

  7. MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)

    前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...

  8. 4.VUE前端框架学习记录四:Vue组件化编码2

    VUE前端框架学习记录四:Vue组件化编码2文字信息没办法描述清楚,主要看编码Demo里面,有附带完整的代码下载地址,有需要的同学到脑图里面自取.脑图地址http://naotu.baidu.com/ ...

  9. vue第四单元(初识vue-在页面中直接引入vue框架-学习使用vue语法-vue的指令-介绍data用法-methods用法)

    第四单元(初识vue-在页面中直接引入vue框架-学习使用vue语法-vue的指令-介绍data用法-methods用法) #课程目标 了解 vue 框架的特点 掌握创建 vue 实例 掌握 data ...

随机推荐

  1. PHP设计模式系列 - 适配器

    什么是适配器: 适配器设计模式只是将某个对象的接口适配为另一个对象所期望的接口. 设计情景: 假如我们原始的有一个UserInfo的类,提供用户信息的类,早起设计该类的时候,只实现了一个getUser ...

  2. 使用FASTJSON做反序列化的时间格式处理

    JSONObject.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.mmm"; Productorder tmp1 = JSONObj ...

  3. Echarts 多曲线“断点”问题解决方法

    Echarts 用来做可视化曲线是非常优秀的一个库.建议使用 Echarts 作为项目的可视化图标库时,仔细研究 官方实例,根据需求来选择类似的示例,下载实例模板来开发,节省时间,减少出错,提高效率. ...

  4. arcgis 10.1 导入数据到oracle 发布地图服务

    机器配置说明 数据库服务器 系统:linux 软件:oracle 11G 64位 Arcgis server服务器 系统:win7 专业版 软件:arcgis server 10.1.win64_11 ...

  5. robotframwork的WEB功能测试(二)—登录

    小结一下截止到目前,我接触的系统的登录模拟. 1. 带token的session:这种用抓包工具很容易抓到,使用这个链接就可以模拟已登录. 2. 使用cookie:有的系统是判断cookie来判断是否 ...

  6. snip

    首先明确物体太小太大都不好检测(都从roi的角度来分析):   1.小物体: a.本身像素点少,如果从anchor的点在gt像素内来说,能提取出来的正样本少    b.小物体会出现iou过低.具体来说 ...

  7. springmvc项目打war包部署到tomcat访问路径去掉项目名

    一般来说,部署到tomcat则是把war包丢到webapps目录下,启动Tomcat会自动解压,成一个war包名称的文件夹项目, 例如imgManager.war 访问的地址一般是localhost: ...

  8. 关于WebSocket长链接的详细介绍iOS

    http://www.cocoachina.com/ios/20181030/25327.html

  9. Kafka设计解析(八)Exactly Once语义与事务机制原理

    转载自 技术世界,原文链接 Kafka设计解析(八)- Exactly Once语义与事务机制原理 本文介绍了Kafka实现事务性的几个阶段——正好一次语义与原子操作.之后详细分析了Kafka事务机制 ...

  10. PH复合电极的结构、测量原理及注意事项

    PH复合电极的结构.测量原理及注意事项 PH计是很多实验中常用的仪器.如细胞培养基的配制.各种洗脱缓冲液的配制等.然而人们很容易忽视它,只知其然不知其所以然.当遇到测量不准确时,往往无从分析.下面从三 ...