osg::Group源码
osg::Group源码
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/ #include <osg/Group>
#include <osg/BoundingBox>
#include <osg/Transform>
#include <osg/OccluderNode>
#include <osg/Geometry>
#include <osg/Notify> #include <stdio.h>
#include <math.h> #include <algorithm> using namespace osg; Group::Group()
{
} Group::Group(const Group& group,const CopyOp& copyop):
Node(group,copyop)
{
for(NodeList::const_iterator itr=group._children.begin();
itr!=group._children.end();
++itr)
{
Node* child = copyop(itr->get());
if (child) addChild(child);
}
} Group::~Group()
{
// remove reference to this from children's parent lists.
for(NodeList::iterator itr=_children.begin();
itr!=_children.end();
++itr)
{
(*itr)->removeParent(this);
} } void Group::traverse(NodeVisitor& nv)
{
for(NodeList::iterator itr=_children.begin();
itr!=_children.end();
++itr)
{
(*itr)->accept(nv);
}
} bool Group::addChild( Node *child )
{
return Group::insertChild( _children.size(), child );
} bool Group::insertChild( unsigned int index, Node *child )
{
if (!child) return false; #if ENSURE_CHILD_IS_UNIQUE
if (containsNode(child))
{
OSG_WARN<<"Adding non unique child to osg::Group, ignoring call"<<std::endl;
return false;
}
#endif // handle deprecated geometry configurations by calling fixDeprecatedData().
osg::Geometry* geometry = child->asGeometry();
if (geometry && geometry->containsDeprecatedData()) geometry->fixDeprecatedData(); // note ref_ptr<> automatically handles incrementing child's reference count.
if (index >= _children.size())
{
index = _children.size(); // set correct index value to be passed to the "childInserted" method
_children.push_back(child);
}
else
{
_children.insert(_children.begin()+index, child);
} // register as parent of child.
child->addParent(this); // tell any subclasses that a child has been inserted so that they can update themselves.
childInserted(index); dirtyBound(); // could now require app traversal thanks to the new subgraph,
// so need to check and update if required.
if (child->getNumChildrenRequiringUpdateTraversal()> ||
child->getUpdateCallback())
{
setNumChildrenRequiringUpdateTraversal(
getNumChildrenRequiringUpdateTraversal()+
);
} // could now require app traversal thanks to the new subgraph,
// so need to check and update if required.
if (child->getNumChildrenRequiringEventTraversal()> ||
child->getEventCallback())
{
setNumChildrenRequiringEventTraversal(
getNumChildrenRequiringEventTraversal()+
);
} // could now require disabling of culling thanks to the new subgraph,
// so need to check and update if required.
if (child->getNumChildrenWithCullingDisabled()> ||
!child->getCullingActive())
{
setNumChildrenWithCullingDisabled(
getNumChildrenWithCullingDisabled()+
);
} if (child->getNumChildrenWithOccluderNodes()> ||
dynamic_cast<osg::OccluderNode*>(child))
{
setNumChildrenWithOccluderNodes(
getNumChildrenWithOccluderNodes()+
);
} return true;
} unsigned int Group::getNumChildren() const
{
return static_cast<unsigned int>(_children.size());
} bool Group::removeChild( Node *child )
{
unsigned int pos = getChildIndex(child);
if (pos<_children.size()) return removeChildren(pos,);
else return false;
} bool Group::removeChildren(unsigned int pos,unsigned int numChildrenToRemove)
{
if (pos<_children.size() && numChildrenToRemove>)
{
unsigned int endOfRemoveRange = pos+numChildrenToRemove;
if (endOfRemoveRange>_children.size())
{
OSG_DEBUG<<"Warning: Group::removeChild(i,numChildrenToRemove) has been passed an excessive number"<<std::endl;
OSG_DEBUG<<" of chilren to remove, trimming just to end of child list."<<std::endl;
endOfRemoveRange=_children.size();
} unsigned int updateCallbackRemoved = ;
unsigned int eventCallbackRemoved = ;
unsigned int numChildrenWithCullingDisabledRemoved = ;
unsigned int numChildrenWithOccludersRemoved = ; for(unsigned i=pos;i<endOfRemoveRange;++i)
{
osg::Node* child = _children[i].get();
// remove this Geode from the child parent list.
child->removeParent(this); if (child->getNumChildrenRequiringUpdateTraversal()> || child->getUpdateCallback()) ++updateCallbackRemoved; if (child->getNumChildrenRequiringEventTraversal()> || child->getEventCallback()) ++eventCallbackRemoved; if (child->getNumChildrenWithCullingDisabled()> || !child->getCullingActive()) ++numChildrenWithCullingDisabledRemoved; if (child->getNumChildrenWithOccluderNodes()> || dynamic_cast<osg::OccluderNode*>(child)) ++numChildrenWithOccludersRemoved; } childRemoved(pos,endOfRemoveRange-pos); _children.erase(_children.begin()+pos,_children.begin()+endOfRemoveRange); if (updateCallbackRemoved)
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-updateCallbackRemoved);
} if (eventCallbackRemoved)
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-eventCallbackRemoved);
} if (numChildrenWithCullingDisabledRemoved)
{
setNumChildrenWithCullingDisabled(getNumChildrenWithCullingDisabled()-numChildrenWithCullingDisabledRemoved);
} if (numChildrenWithOccludersRemoved)
{
setNumChildrenWithOccluderNodes(getNumChildrenWithOccluderNodes()-numChildrenWithOccludersRemoved);
} dirtyBound(); return true;
}
else return false;
} bool Group::replaceChild( Node *origNode, Node *newNode )
{
if (newNode==NULL || origNode==newNode) return false; unsigned int pos = getChildIndex(origNode);
if (pos<_children.size())
{
return setChild(pos,newNode);
}
return false;
} bool Group::setChild( unsigned int i, Node* newNode )
{
if (i<_children.size() && newNode)
{ ref_ptr<Node> origNode = _children[i]; // first remove for origNode's parent list.
origNode->removeParent(this); // note ref_ptr<> automatically handles decrementing origNode's reference count,
// and inccrementing newNode's reference count.
_children[i] = newNode; // register as parent of child.
newNode->addParent(this); dirtyBound(); // could now require update traversal thanks to the new subgraph,
// so need to check and update if required.
int delta_numChildrenRequiringUpdateTraversal = ;
if (origNode->getNumChildrenRequiringUpdateTraversal()> ||
origNode->getUpdateCallback())
{
--delta_numChildrenRequiringUpdateTraversal;
}
if (newNode->getNumChildrenRequiringUpdateTraversal()> ||
newNode->getUpdateCallback())
{
++delta_numChildrenRequiringUpdateTraversal;
} if (delta_numChildrenRequiringUpdateTraversal!=)
{
setNumChildrenRequiringUpdateTraversal(
getNumChildrenRequiringUpdateTraversal()+delta_numChildrenRequiringUpdateTraversal
);
} // could now require event traversal thanks to the new subgraph,
// so need to check and Event if required.
int delta_numChildrenRequiringEventTraversal = ;
if (origNode->getNumChildrenRequiringEventTraversal()> ||
origNode->getEventCallback())
{
--delta_numChildrenRequiringEventTraversal;
}
if (newNode->getNumChildrenRequiringEventTraversal()> ||
newNode->getEventCallback())
{
++delta_numChildrenRequiringEventTraversal;
} if (delta_numChildrenRequiringEventTraversal!=)
{
setNumChildrenRequiringEventTraversal(
getNumChildrenRequiringEventTraversal()+delta_numChildrenRequiringEventTraversal
);
} // could now require disabling of culling thanks to the new subgraph,
// so need to check and update if required.
int delta_numChildrenWithCullingDisabled = ;
if (origNode->getNumChildrenWithCullingDisabled()> ||
!origNode->getCullingActive())
{
--delta_numChildrenWithCullingDisabled;
}
if (newNode->getNumChildrenWithCullingDisabled()> ||
!newNode->getCullingActive())
{
++delta_numChildrenWithCullingDisabled;
} if (delta_numChildrenWithCullingDisabled!=)
{
setNumChildrenWithCullingDisabled(
getNumChildrenWithCullingDisabled()+delta_numChildrenWithCullingDisabled
);
} // could now require disabling of culling thanks to the new subgraph,
// so need to check and update if required.
int delta_numChildrenWithOccluderNodes = ;
if (origNode->getNumChildrenWithOccluderNodes()> ||
dynamic_cast<osg::OccluderNode*>(origNode.get()))
{
--delta_numChildrenWithOccluderNodes;
}
if (newNode->getNumChildrenWithOccluderNodes()> ||
dynamic_cast<osg::OccluderNode*>(newNode))
{
++delta_numChildrenWithOccluderNodes;
} if (delta_numChildrenWithOccluderNodes!=)
{
setNumChildrenWithOccluderNodes(
getNumChildrenWithOccluderNodes()+delta_numChildrenWithOccluderNodes
);
} return true;
}
else return false; } BoundingSphere Group::computeBound() const
{
BoundingSphere bsphere;
if (_children.empty())
{
return bsphere;
} // note, special handling of the case when a child is an Transform,
// such that only Transforms which are relative to their parents coordinates frame (i.e this group)
// are handled, Transform relative to and absolute reference frame are ignored. BoundingBox bb;
bb.init();
NodeList::const_iterator itr;
for(itr=_children.begin();
itr!=_children.end();
++itr)
{
osg::Node* child = itr->get();
const osg::Transform* transform = child->asTransform();
if (!transform || transform->getReferenceFrame()==osg::Transform::RELATIVE_RF)
{
osg::Drawable* drawable = child->asDrawable();
if (drawable)
{
bb.expandBy(drawable->getBoundingBox());
}
else
{
const osg::BoundingSphere& bs = child->getBound();
bb.expandBy(bs);
}
}
} if (!bb.valid())
{
return bsphere;
} bsphere._center = bb.center();
bsphere._radius = 0.0f;
for(itr=_children.begin();
itr!=_children.end();
++itr)
{
osg::Node* child = itr->get();
const osg::Transform* transform = child->asTransform();
if (!transform || transform->getReferenceFrame()==osg::Transform::RELATIVE_RF)
{
const BoundingSphere& bs = child->getBound();
bsphere.expandRadiusBy(bs);
}
} return bsphere;
} void Group::setThreadSafeRefUnref(bool threadSafe)
{
Node::setThreadSafeRefUnref(threadSafe); for(NodeList::const_iterator itr=_children.begin();
itr!=_children.end();
++itr)
{
(*itr)->setThreadSafeRefUnref(threadSafe);
}
} void Group::resizeGLObjectBuffers(unsigned int maxSize)
{
Node::resizeGLObjectBuffers(maxSize); for(NodeList::const_iterator itr=_children.begin();
itr!=_children.end();
++itr)
{
(*itr)->resizeGLObjectBuffers(maxSize);
}
} void Group::releaseGLObjects(osg::State* state) const
{
Node::releaseGLObjects(state); for(NodeList::const_iterator itr=_children.begin();
itr!=_children.end();
++itr)
{
(*itr)->releaseGLObjects(state);
}
}
osg::Group源码的更多相关文章
- osg::Node源码
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source ...
- [源码解析] GroupReduce,GroupCombine 和 Flink SQL group by
[源码解析] GroupReduce,GroupCombine和Flink SQL group by 目录 [源码解析] GroupReduce,GroupCombine和Flink SQL grou ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- 【原】AFNetworking源码阅读(四)
[原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...
- 多线程爬坑之路-Thread和Runable源码解析
多线程:(百度百科借一波定义) 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提 ...
- 搭建LNAMP环境(二)- 源码安装Nginx1.10
上一篇:搭建LNAMP环境(一)- 源码安装MySQL5.6 1.yum安装编译nginx需要的包 yum -y install pcre pcre-devel zlib zlib-devel ope ...
- iOS开发之Alamofire源码解析前奏--NSURLSession全家桶
今天博客的主题不是Alamofire, 而是iOS网络编程中经常使用的NSURLSession.如果你想看权威的NSURLSession的东西,那么就得去苹果官方的开发中心去看了,虽然是英文的,但是结 ...
- CRL2.3(ORM开发框架)源码github发布
简介 CRL是一个面向对象的轻便型ORM业务框架 此框架追求的是使用简单,方便,因此设计为: 不需要代码生成器生成对象类,按标准方式写即可 依托lambda,实现语法解析转换为等效的SQL查询,完全以 ...
- ZFPlayer 源码解读
源码下载地址:https://github.com/renzifeng/ZFPlayer 之前自己实现过一个模仿百思不得姐的demo https://github.com/agelessman/FFm ...
随机推荐
- windows 任务计划
我的需求是每天定时访问网站的某一个控制器去刷新库存 流程如下(我自己的理解) 进入任务计划页面 上图指定的bat文件内容就是访问指定的网站路径 dingshi.bat文件内容如下(这个是网上找的,可能 ...
- TensorFlow 2 快速教程,初学者入门必备
TensorFlow 2 简介 TensorFlow 是由谷歌在 2015 年 11 月发布的深度学习开源工具,我们可以用它来快速构建深度神经网络,并训练深度学习模型.运用 TensorFlow 及其 ...
- k8s之volume
pause容器为基础架构容器,每一个节点都有一个pause镜像, 为每一个pod提供底层基础支撑设备,所有pod中容器会共享此容器的网络空间,存储卷也是 还可使用csi,存储插件. 使用存储卷步骤1. ...
- 数据库开发-pymysql详解
数据库开发-pymysql详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Python支持的MySQL驱动 1>.什么是驱动 与MySQL通信就是典型的CS模式.Se ...
- HTML&CSS基础-html的图片标签
HTML&CSS基础-html的图片标签 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.如下图所示,准备一张图片,存放路径和html文件在同一目录 二.HTML源代码 ...
- supervisor安装部署文档和管理实例
Supervisord是用Python实现的一款非常实用的进程管理工具,类似于monit(关于monit见我的博客:用monit监控系统关键进程),monit和supervisord的一个比较大的差异 ...
- 使用laravel jwt-auth post提交数据一直出现 'error' => 'invalid_credentials'
注意,laravel 对密码使用Hash加密,检查一下数据库user表中的password有没有Hash加密过 没仔细看文档坑死我了
- new 的对象如何不分配在堆而分配在栈上(方法逃逸等)
当能够明确对象不会发生逃逸时,就可以对这个对象做一个优化,不将其分配到堆上,而是直接分配到栈上,这样在方法结束时,这个对象就会随着方法的出栈而销毁,这样就可以减少垃圾回收的压力. 如方法逃逸. 逃逸分 ...
- 最详细的keepalived+lvs-dr配置文档
四台台机器: 分发器主:192.168.0.154 分发器备:192.168.0.171 rs_1:192.168.0.131 rs_2:192.168.0.132 keepalived安装: yum ...
- HTML——MP4视频不能播放
前言 HTML5中提供了video标签,但是为什么有的MP4视频可以播放,有的不能播放呢? 简介 当然是因为编码的问题咯~ 视频格式 标签属性 DOM参考 HTML 5 视频/音频参考手册 使用 &l ...