zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    最详尽的IntelliJ IDEA项目web项目搭建!!!!!!
    Unable to locate JAR/zip in file system as specified by the driver definition: ojdbc14.jar
    Caused by: org.hibernate.HibernateException: Unable to build the default ValidatorFactory
    MySQL闪退
    mysql:unknown variable 'default -collation=utf8_general_ci'
    更改文本的编码jsp.xml.java
    save is not valid without active transaction
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'deptDao_a' defined in class path resource [beansAndHibernate.xml]: Cannot resolve reference to bean 'sessionFact
    java.lang.ClassNotFoundException: org.springframework.orm.hibernate3.LocalSessionFactoryBean
    linux常用Java程序员使用命令(二)
  • 原文地址:https://www.cnblogs.com/ccentry/p/10261979.html
Copyright © 2011-2022 走看看