osg::NodeVisitor中计算一个节点对应的世界变换矩阵、法向量、顶点坐标

class MyNodeVisitor:public osg::NodeVisitor

{

pulic:

  MyNodeVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)

  {}

  void apply(osg::Geode& geode)

  {

    //计算当前geode节点对应的世界变换矩阵,用来计算geode中顶点对应的世界坐标

    osg::Matrix geodeMatrix=osg::computeLocalToWorld(getNodePath());

    

    unsigned int count=geode.getNumDrawables();

    for(unsigned int geomIdx=0; geomIdx<count; geomIdx++)

    {

      osg::Geometery *geometry = geode.getDrawable(geomIdx)->asGeometry();

      if(!geometry) continue;

      //顶点数据

      osg::Vec3Array* vertices=dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());

      //法向量

      osg::Vec3Array* normals=dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());

      //索引数组

      for(unsigned int primitiveIdx=0; primitiveIdx<geometry->getNumPrimitiveSets(); ++primitiveIdx)

      {

        osg::PrimitiveSet* ps=geometry->getPrimitiveSet(primitiveIdx);

        if(!ps) continue;

        switch(ps->getType())

        {

          case osg::PrimitiveSet::DrawElementsUShortPrimitiveType:

          {

            osg::DrawElementsUShort* deus=dynamic_cast<osg::DrawElementsUShort*>(ps);

            const unsigned int indexNum=deus->getNumIndices();

            switch(deus->getMode)

            {

            case osg::PrimitiveSet::TRIANGLES:

            //假设geometry->getNormalBinding()==osg::Geometry::BIND_PER_VERTEX)

            //即每一个顶点对应一个法向量

            for(unsigned int i=0; i<indexNum; i++)

            {

              //顶点索引

              unsigned int idx=deus->at(i);

              //法向量。需要转换成世界坐标,需要乘以geodeMatrix的逆矩阵的转置,具体原因可以参考计算法向量那篇随笔

              Vec3 normalWorld=normals->at(idx)*(geodeMatrix的逆矩阵的转置);

              //顶点坐标

              Vec3 vertexWorld=vertices->at(idx)*geodeMatrix;

            }

            break;

            }

          }

        }

      }

    }

  }

}

时间: 2024-08-03 07:10:01

osg::NodeVisitor中计算一个节点对应的世界变换矩阵、法向量、顶点坐标的相关文章

二叉树中删除一个节点

二叉树的删除可以算是二叉树最为复杂的操作,删除的时候要考虑到很多种情况: 1.被删除的节点是叶子节点 2.被删除的节点只有左孩子节点 3.被删除的节点只有右孩子节点 4.被删除的有两个孩子节点 所以在删除的时候,这4种情况都必须考虑进去,并且这4中情况之下,还会有细的划分,下面就细说怎么删除. 在二叉树中想要删除一个节点,首先需要找到这个节点,由于二叉树在插入节点的时候会遵循一个原则,就是利用节点的值来判断 节点将被插入的位置(或者给节点加一个key,用key来判断).从根节点开始往下走,比当前

[华为机试练习题]49.向升序单向链表中插入一个节点

题目 描述: 输入一个升序单向链表和一个链表节点,向单向链表中按升序插入这个节点. 输入为空指针的情况视为异常,另外不考虑节点值相等的情况. 链表结点定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; }; 详细描述: 接口说明 原型: ListNode* InsertNodeToList(ListNode* pListHead, ListNode* pInsertNode); 输入参数: ListNode* pListHead 单向链表

链表中插入一个节点的三种情况

在链表中插入一个元素可以分为三种情况: 1.在节点的时候 2.在链表中间的任意位置 3.在链表的最后位置,也可以认为这种情况为追加(这个就留到追加的时候来实现) 下面是代码的实现 SN *Insert_S_Node( SN *head ) /* 传入的参数是被插入链表中的头指针 */ { SN *Insert_Node=NULL, *Dest_Node = NULL; /* Insert_Node是将要做成的新链表中的节点 Dest_Node是要插入的节点*/ INT32 OSM = 1, i3

向升序单向链表中插入一个节点

#include "OJ.h" /* 功能: 输入一个升序单向链表和一个链表节点,向单向链表中按升序插入这个节点. 输入为空指针的情况视为异常,另外不考虑节点值相等的情况. 输入: ListNode* pListHead 单向链表 ListNode* pInsertNode 新插入节点 输出: ListNode* pListHead 单向链表 返回: 正常插入节点返回链表头指针,其它异常返回空指针 */ ListNode* InsertNodeToList(ListNode* pLis

在MySQL查询中计算一个人的年龄——续

DATE_ADD来救援 MySQL知道如何使用Gregorian日历,我相信让MySQL更容易完成工作,而不是试图弄清楚如何实现不同的情况.我选择实施"月末最后一天"技术.在这种情况下,我们将通过创建基于当年3月1日的mysql日期,并从中减去一天来到达2月的最后一天. 如果您使用mysql日期函数阅读我的文章"查找下一个星期一",您会看到如何使用DATE_ADD()来帮助解决许多问题,即使在您实际使用它减去时该名称可能会产生误导.使用以下测试日期证明mysql已经

[012]链表笔记--在链表中插入一个节点

插入的数目为num,如果比head小,则插在链表头:如果比链表中元素都大,则插在结尾:否则插在链表中: 代码如下: 1 Link* Link::Add(Link* pLink, int num) { 2 Link *p1,*p2; 3 p1 = pLink; 4 Link *p0 = new Link; 5 p0->id = num; 6 7 while ((p0->id > p1->id) && (p1->next != NULL)) { 8 p2 = p1

在二叉树中找到一个节点的后继节点

题目思路 题目来源 C++代码实现 /* struct TreeLinkNode { int val; struct TreeLinkNode *left; struct TreeLinkNode *right; struct TreeLinkNode *next; TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) { } }; */ class Solution { public: TreeLinkNode* Ge

java中计算一个方法执行时长,耗费单位(秒)

long startTime=System.currentTimeMillis(); //执行方法 long endTime=System.currentTimeMillis(); float excTime=(float)(endTime-startTime)/1000; System.out.println("执行时间:"+excTime+"s");

450. Delete Node in a BST 删除bst中的一个节点

[抄题]: Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST. Basically, the deletion can be divided into two stages: Search for a node to remove. If