WebGL——osg框架学习四

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

 1 /*
 2 绘制对象角色
 3  */
 4 let DrawActor = require(‘./DrawActor‘);
 5 let Geometry = require(‘../core/Geometry‘);
 6 let StateSet = require(‘../core/StateSet‘);
 7 let RenderEntity = require(‘../scene/RenderEntity‘);
 8 let SceneRoot = require(‘../scene/SceneRoot‘);
 9 let BoundingBox = require(‘../util/BoundingBox‘);
10
11 let DrawEntityActor = function (renderer) {
12     DrawActor.call(this, renderer);
13
14     this._currentRenderEntity = undefined;//当前处理的渲染实体,临时数据
15     this._currentMaterial = undefined;//当前默认颜色状态,临时数据
16     this._isEntityMaterial = false;//临时数据,实体的材质无脑取最上面的节点
17     this._currentBoundingBox = new BoundingBox();//计算RenderEntity包围盒,临时数据
18 };
19
20 DrawEntityActor.prototype = Object.create(DrawActor.prototype);
21 DrawEntityActor.prototype.constructor = DrawEntityActor;

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

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

 1 //重载
 2     pushStateSet: function (stateset) {
 3         if (stateset) {
 4             if (this._isEntityMaterial) {
 5                 if (stateset.isMaterialAttribute()) {
 6                     if (this._currentMaterial === undefined) {
 7                         this._currentMaterial = stateset;//无脑取最上面的,实体的颜色状态是这样
 8                     }
 9                 } else {
10                     //添加StateGraph子节点,更新当前活动的StateGraph为新的状态
11                     this._currentStateBin = this._currentStateBin.addStateSetChild(stateset);
12                 }
13             }
14             else {
15                 //添加StateGraph子节点,更新当前活动的StateGraph为新的状态
16                 this._currentStateBin = this._currentStateBin.addStateSetChild(stateset);
17             }
18         }
19     },

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

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

 1 popStateSet: function (stateset) {//重载
 2         if (stateset) {
 3             if(this._isEntityMaterial){
 4                 if (stateset.isMaterialAttribute()) {//几何级别是最底层,这时才能置空
 5                     if (this._currentMaterial === stateset) {
 6                         this._currentMaterial = undefined;
 7                     }
 8                  } else {
 9                     this._currentStateBin = this._currentStateBin.getParent();
10                 }
11             }else{
12                 this._currentStateBin = this._currentStateBin.getParent();
13             }
14         }
15     },

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

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

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

 1 /*
 2 提前遍历RenderEntity的目的
 3 确认每个drawable的世界坐标变换,确认除RenderEntity外的状态树
 4 相机树基本不用考虑,只有主相机
 5  */
 6 DrawEntityActor.prototype[SceneRoot.typeID] = function (root) {
 7     DrawActor.prototype[SceneRoot.typeID].call(this, root);
 8
 9     //更新根节点的包围球
10     this._sceneRoot.getBoundingSphere().expandByBoundingBox(this._sceneRoot.getBoundingBox());
11 };
12 //RenderEntity
13 DrawEntityActor.prototype[RenderEntity.typeID] = function (Rentity) {
14     this._currentStateBin = this._baseState;
15     this._currentRenderEntity = Rentity;
16     this._currentMaterial = undefined;
17     this._isEntityMaterial = true;
18
19     //这里RenderEntity的状态不考虑,RenderEntity的状态在实时渲染时起作用
20     this.traverse(Rentity);
21
22     this._isEntityMaterial = false;
23
24     //直接求得包围盒
25     let bb = new BoundingBox();
26     bb.copy(this._currentBoundingBox);
27     Rentity.setBoundingBox(bb);
28     this._sceneRoot.getBoundingBox().expandByBoundingBox(Rentity.getBoundingBox());//扩充包围盒
29
30     //重置引用,为下次使用准备
31     this._currentRenderEntity = undefined;
32     this._currentMaterial = undefined;
33     this._currentBoundingBox.reset();
34 };
35 //Geometry已经是叶子,不需要继续递归了
36 DrawEntityActor.prototype[Geometry.typeID] = function (geometry) {
37     let stateset = geometry.getStateSet();
38     this.pushStateSet(stateset, true);
39     this.pushDrawable(geometry);
40     this.popStateSet(stateset);
41 };
42 module.exports = DrawEntityActor;

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

原文地址:https://www.cnblogs.com/ccentry/p/10261979.html

时间: 2024-10-06 11:05:53

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

WebGL——osg框架学习一

从今天开始,我们开始正式的学习osg框架,今天我们学习的是osg的渲染模块,我们来看一下代码结构. 所有DrawXXX的js模块都是渲染的模块,我们逐一来简单介绍一下,第一个Drawable.js,这个模块是描述可绘制对象的类,也是我们今天要讨论的类.在osg框架中,渲染管道在准备时期首先要统计管理可绘制对象,我们来看看Drawable模块到底做了什么操作,进行了哪些管理.先贴出代码. /* 可绘制对象 */ let StateBin = require('./StateBin'); let B

Laravel框架学习(四)

一. composer的安装: 1.Composer是什么? 是 PHP 用来管理依赖(dependency)关系的工具. 你可以在自己的项目中声明所依赖的外部工具库(libraries), Composer 会帮你安装这些依赖的库文件. 2.网址:https://getcomposer.org 下载:https://getcomposer.org/download/ 中国全量镜像:http://pkg.phpcomposer.com/ 启用本镜像服务命令: composer config -g

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

PS:Force Is Meaningless Without Skill 学习内容: 1.使用AndBase实现单线程任务... 2.使用AndBase实现多线程任务...   AndBase内部封装了多种方法,我们可以使用这些方法构建单线程任务和多线程任务..一般线程任务用于执行耗时的操作...比如说下载什么安装包,文件等数据量较大的东西,我们是必须要开启一个异步线程或者是同步线程来执行操作...如果任务过多,那么我们就可以使用任务请求队列或者是线程池来处理多个任务...这样可以节省很多的时

spring框架学习(四)自动装配

spring框架学习(四)自动装配 set注入和构造注入有时在做配置时比较麻烦.所以框架为了提高开发效率,提供自动装配功能,简化配置.Spring框架式默认不支持自动装配的,要想使用自动装配需要修改spring配置文件中<bean>标签的autowire属性 自动装配属性有6个值可选,分别代表不同的含义. 1,byName 从Spring环境中获取目标对象时,目标对象中的属性会根据名称在整个Spring环境中查找<bean>标签的id属性值.如果有相同的,那么获取这个对象,实现关联

MVC系列——MVC源码学习:打造自己的MVC框架(四:自定义视图)

前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾.对于这个系列,通过学习源码,博主也学到了很多东西,在此还是把博主知道的先发出来,供大家参考. 本文原创地址:http://www.cnblogs.com/landeanfen/p/6019719.html MVC源码学习系列文章目录: MVC系列——MVC源码学习:打造自己的MVC框架(一) MVC

Silverlight学习(四) domainservice动态多条件查询

上次讲了silverlight+MVVN+EF的简单框架,能够实现简单的数据CURD,但是多条件动态的查询一直没有实现.在网上查阅了很多资料,发现自己走了很多误区,代码很难调试正确. 这次的查询是基于上次的查询,只是增加了一个查询条件,动态多条件的查询的重点是获取查询的语言. 1 private string GetSql() 2 { 3 string query = "1=1"; 4 if (!string.IsNullOrEmpty(searchText.name)) 5 { 6

Struts2框架学习(三) 数据处理

Struts2框架学习(三) 数据处理 Struts2框架框架使用OGNL语言和值栈技术实现数据的流转处理. 值栈就相当于一个容器,用来存放数据,而OGNL是一种快速查询数据的语言. 值栈:ValueStack一种数据结构,操作数据的方式为:先进后出 OGNL : Object-GraphNavigation Language(对象图形导航语言)将多个对象的关系使用一种树形的结构展现出来,更像一个图形,那么如果需要对树形结构的节点数据进行操作,那么可以使用 对象.属性 的方式进行操作,OGNL技

JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue

前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的文章,大多都是以罗列记忆点的形式书写的,没有谈论实现细节和逻辑原理.作为个人笔记无可厚非,但是并不利于他人学习.希望能通过这种比较“费劲”的讲解,帮助我自己.也帮助读者们更好地学习Java.掌握Java. 无论你跟我一样需要应聘,还是说在校学生学习Java基础,都对入门和进一步启发学习有所帮助.(关

Spring框架学习1

AnonymouL 兴之所至,心之所安;尽其在我,顺其自然 新随笔 管理 Spring框架学习(一) 阅读目录 一. spring概述 核心容器: Spring 上下文: Spring AOP: Spring DAO: Spring ORM: Spring Web 模块: Spring MVC 框架: 二.实例化spring容器 三.利用Spring容器创建javaBean对象 1,用构造器实例化 2,使用静态工厂方法实例化 3,实例工厂实例化 四,容器的IOC应用 4.1)Set注入 4.2)