查看: 4194|回复: 10

让模型包围盒随模型的运动一起变化

[复制链接]

该用户从未签到

发表于 2011-12-9 11:50:54 | 显示全部楼层 |阅读模式
头文件省略;
运动代码省略;
包围盒代码如下:
osg::ComputeBoundsVisitor cbv;    //调用计算包围盒访问器类
osg::BoundingBox bb;    //调用获得包围盒的类

osg::ref_ptr<osg::Geode> boundingBoxGeode = new osg::Geode;

//osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;    //相应更新、渲染
osg::ref_ptr<osg::Geode> createBoundingBox(osg::BoundingBox &box)    //创建包围盒的函数
{
  osg::ref_ptr<osg::Geode> geode = new osg::Geode;    //返回几何节点Geode
  //根据求得的节点长宽高,画出包围盒
  float lengthX = box.xMax() - box.xMin();    //包围盒x方向的最大值减去x方向的最小值
  float lengthY = box.yMax() - box.yMin();
  float lengthZ = box.zMax() - box.zMin();

  osg::ref_ptr<osg::ShapeDrawable> sd = new osg::ShapeDrawable(new osg::Box(box.center(), lengthX, lengthY, lengthZ));    //几何参数指针
  osg::ref_ptr<osg::Vec3Array> colors = new osg::Vec3Array;    //表示颜色的指针

  sd->setColor(osg::Vec4(1,0,0,1));    //将颜色参数传给几何模型
  osg::ref_ptr<osg::StateSet> state = sd->getOrCreateStateSet();    //状态设置指针
  osg::ref_ptr<osg:olygonMode> pm = new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode:INE);    //多边形模型指针
  state->setAttributeAndModes(pm.get());

  //设置线宽
  osg::ref_ptr<osg::LineWidth> lw = new osg::LineWidth(1.0f);
  state->setAttribute(lw.get());
  geode->addDrawable(sd.get());

  return geode.get();
}


int  main( )
{

        osg::ref_ptr<osg::Group> root = new osg::Group;    //返回root智能指针,指向osg::Group,所有加入场景中的数据都会加入到Group当中
    osg::ref_ptr<osg::Group> testGroup = new osg::Group;
        osg::ref_ptr<osg::Group> testGroup2 = new osg::Group;
       

        osg::Group* crane = NULL;

        crane = dynamic_cast<osg::Group*>
                (osgDB::readNodeFile("crane.ive"));

        crane->accept( *(new findNodeVisitor(" ")) );

        root->addChild(crane);

        findNodeVisitor findcraneNode ("DOF1");

        crane->accept(findcraneNode);

        osg::ref_ptr<osg::PositionAttitudeTransform> craneDOF = dynamic_cast<osg::PositionAttitudeTransform* >(findcraneNode.getFirst());
       
        if( craneDOF)
        {
        //调用createpath1函数完成回转运动,设置循环模式为NO_LOOP,设置AnimationPathCallback对象为DOF1节点
        osg::AnimationPath* path1 = createpath1();                              
        path1->setLoopMode(osg::AnimationPath::NO_LOOPING);
        craneDOF->setUpdateCallback(new osg::AnimationPathCallback(path1));

        craneDOF->setPosition(osg::Vec3(-4.0, 0.0, 8.0));    //将坐标位置参数传到boxPAT节点
        craneDOF->setScale(osg::Vec3(0.18, 0.9, 0.03));    //将表示大小的参数传到boxPAT节点
        testGroup->addChild(craneDOF.get());
        testGroup->accept(cbv);
        bb = cbv.getBoundingBox();
    boundingBoxGeode = createBoundingBox(bb);
    root->addChild(boundingBoxGeode.get());
        root->addChild(testGroup.get());    //将testGroup节点的参数传到根节点root下
        }
        findNodeVisitor findzhubiNode("DOF2");
       
        crane->accept(findzhubiNode);

   //设置动态变换——为指定的“名字”定义一节点
        osg::ref_ptr<osg::PositionAttitudeTransform> zhubiDOF = dynamic_cast<osg::PositionAttitudeTransform* >(findcraneNode.getFirst());

        if(zhubiDOF)
        {
        //调用createpath2函数完成变幅运动,设置循环模式为NO_LOOP,设置AnimationPathCallback对象为DOF2节点
        osg::AnimationPath* path2 = createpath2();
        path2->setLoopMode(osg::AnimationPath::NO_LOOPING);
        zhubiDOF->setUpdateCallback(new osg::AnimationPathCallback(path2));

        zhubiDOF->setScale(osg::Vec3(0.1, 0.1, 1.06));    //将表示大小的参数传到boxPAT节点
        testGroup2->addChild(zhubiDOF.get());
        testGroup2->accept(cbv);
        bb = cbv.getBoundingBox();
        testGroup2->dirtyBound();    //更新testGroup
    boundingBoxGeode = createBoundingBox(bb);
    root->addChild(boundingBoxGeode.get());
        root->addChild(testGroup2.get());    //将testGroup节点的参数传到根节点root下
        }

        osgViewer::Viewer viewer;

        viewer.setSceneData( root.get());
        //viewer->setCameraManipulator( new osgGA::TrackballManipulator);
        viewer.realize();
        viewer.run();
        return 0;
}

问题:包围盒已经建立起来了,就是物体运动的时候,包围盒不随着运动而变化。谢谢各位帮忙啊!~!
运动后位置.JPG
初始位置.JPG

该用户从未签到

发表于 2011-12-9 12:18:18 | 显示全部楼层
将你的包围盒节点和物体节点的运动关联起来

该用户从未签到

 楼主| 发表于 2011-12-9 12:49:16 | 显示全部楼层
fenma3422 发表于 2011-12-9 12:18
将你的包围盒节点和物体节点的运动关联起来

如何关联啊?用到什么相关代码呢?
如我的包围盒节点是testGroup2,控制物体运动的代码为:
osg::AnimationPath* createpath2()
{

        osg::Vec3  yoz(1.0,0.0,0.0), xoz(0.0,1.0,0.0), xoy(0.0,0.0,1.0);
        osg::ref_ptr<osg::AnimationPath> path2 = new osg::AnimationPath;
        path2->insert(8.0,
                osg::AnimationPath::ControlPoint(osg::Vec3(0.0,0.0,2.0), osg:uat(0.0,yoz,osg:egreesToRadians(-30.0),osg::Y_AXIS,0.0,xoy)));
        path2->insert(14.0,
                osg::AnimationPath::ControlPoint(osg::Vec3(0.0,0.0,2.0), osg::Quat(0.0,yoz,osg::DegreesToRadians(-60.0),osg::Y_AXIS,0.0,xoy)));
        path2->insert(20.0,
                osg::AnimationPath::ControlPoint(osg::Vec3(0.0,0.0,2.0), osg::Quat(0.0,yoz,osg::DegreesToRadians(-30.0),osg::Y_AXIS,0.0,xoy)));
       
        return path2.release();

}

我该如何做呢?

该用户从未签到

发表于 2011-12-9 13:24:20 | 显示全部楼层
你把作用懂啊物体的变换也作用到你的包围盒上即可

该用户从未签到

 楼主| 发表于 2011-12-9 16:54:55 | 显示全部楼层
fenma3422 发表于 2011-12-9 13:24
你把作用懂啊物体的变换也作用到你的包围盒上即可

我把包围盒节点跟物体的运动关联起来了,可绘出的包围盒还是不动啊~~~该怎么搞啊~~是不是我包围盒有问题啊

该用户从未签到

发表于 2011-12-9 22:08:55 | 显示全部楼层
应该是你关联的问题,就是说的path动画也得作用到包围盒上,简单的你把包围盒节点作为路径动画所关联的MT节点的子节点也可

该用户从未签到

 楼主| 发表于 2011-12-12 16:58:21 | 显示全部楼层
fenma3422 发表于 2011-12-9 22:08
应该是你关联的问题,就是说的path动画也得作用到包围盒上,简单的你把包围盒节点作为路径动画所关联的MT节 ...

我添加了一个MT节点了,只是多出了一个运动的物体,包围盒还是不动啊~~我把代码贴上去,谢谢帮我调试一下吧,谢谢啊~!

代码如下:

#include <osg/Group>
#include <osg/Node>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/PositionAttitudeTransform>
#include <osg/NodeCallback>
#include <osg/MatrixTransform>
#include <osgGA/TrackballManipulator>
#include <osgViewer/Viewer>
#include <iostream>
#include <osg/io_utils>
#include <osg/Geometry>
#include <osg/Shape>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/Object>

#include <Windows.h>
#include <vector>
#include <osg/Timer>
#include <osg/Switch>
#include <osg/NodeVisitor>
#include <osg/BoundingBox>
#include <osg/BoundingSphere>
#include <osgGA/GUIEventHandler>
#include <osg/ComputeBoundsVisitor>
#include <osg/StateSet>
#include <osg/LineWidth>
#include <osg/PolygonMode>

osg::ref_ptr<osg:ositionAttitudeTransform> ganPAT = new osg::PositionAttitudeTransform;    //返回boxPAT智能指针
osg::ref_ptr<osg::PositionAttitudeTransform> testPAT = new osg::PositionAttitudeTransform;
osg::ref_ptr<osg::Group> root = new osg::Group;    //返回root智能指针,指向osg::Group,所有加入场景中的数据都会加入到Group当中
osg::ref_ptr<osg::Group> testGroup = new osg::Group;
osg::ref_ptr<osg::MatrixTransform> gantrans=new osg::MatrixTransform;
osg::ComputeBoundsVisitor cbv;    //调用计算包围盒访问器类
osg::BoundingBox bb;    //调用获得包围盒的类

osg::AnimationPath* createpath1()
{
        osg::Vec3  yoz(1.0,0.0,0.0), xoz(0.0,1.0,0.0), xoy(0.0,0.0,1.0);
        osg::ref_ptr<osg::AnimationPath> path1 = new osg::AnimationPath;
        path1->insert(0.0,
                osg::AnimationPath::ControlPoint(osg::Vec3(0.0,0.0,0.0),osg:uat(0.0,yoz,0.0,xoz,0.0,xoy)));
        //path1->insert(4.0,
        //        osg::AnimationPath::ControlPoint( osg::Vec3(0.0,0.0,0.0),osg::Quat(0.0,yoz,osg::PI_2/3,xoz,0.0,xoy)));
        //path1->insert(6.0,
        //        osg::AnimationPath::ControlPoint( osg::Vec3(0.0,0.0,0.0),osg::Quat(0.0,yoz,osg::PI_2/6,xoz,0.0,xoy)));
        path1->insert(18.0,
                osg::AnimationPath::ControlPoint( osg::Vec3(0.0,0.0,0.0),osg::Quat(0.0,yoz,osg::PI_2,xoz,0.0,xoy)));

        return path1.release();

}



osg::ref_ptr<osg::Geode> boundingBoxGeode = new osg::Geode;
osg::ref_ptr<osg::Geode> createBoundingBox(osg::BoundingBox &box)    //创建包围盒的函数
{
        osg::ref_ptr<osg::Geode> boundingBoxGeode = new osg::Geode;

        osg::ref_ptr<osg::MatrixTransform> boxBounding=new osg::MatrixTransform;

  osg::ref_ptr<osg::Geode> geode = new osg::Geode;    //返回几何节点Geode
  //根据求得的节点长宽高,画出包围盒
  float lengthX = box.xMax() - box.xMin();    //包围盒x方向的最大值减去x方向的最小值
  float lengthY = box.yMax() - box.yMin();
  float lengthZ = box.zMax() - box.zMin();

  osg::ref_ptr<osg::ShapeDrawable> sd = new osg::ShapeDrawable(new osg::Box(box.center(), lengthX, lengthY, lengthZ));    //几何参数指针
  osg::ref_ptr<osg::Vec3Array> colors = new osg::Vec3Array;    //表示颜色的指针

  sd->setColor(osg::Vec4(1,0,0,1));    //将颜色参数传给几何模型
  osg::ref_ptr<osg::StateSet> state = sd->getOrCreateStateSet();    //状态设置指针
  osg::ref_ptr<osg::PolygonMode> pm = new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode:INE);    //多边形模型指针
  state->setAttributeAndModes(pm.get());

  //设置线宽
  osg::ref_ptr<osg::LineWidth> lw = new osg::LineWidth(1.0f);
  state->setAttribute(lw.get());
  geode->addDrawable(sd.get());

  boxBounding->addChild(geode.get());

  return geode.get();
}


int main()
{
        osg::ref_ptr<osg::MatrixTransform>  gan = new osg::MatrixTransform;
        gan->addChild(osgDB::readNodeFile("gan.IVE"));

    ganPAT->addChild(gan.get());    //获取boxNode节点的参数传到boxPAT节点
    //ganPAT->setPosition(osg::Vec3(10.0, 0.0, 0.0));    //将坐标位置参数传到boxPAT节点
    ganPAT->setScale(osg::Vec3(1.0, 1.0, 1.0));    //将表示大小的参数传到boxPAT节点
        ganPAT->accept(cbv);    //计算Group中的包围盒的函数accept传到testGroup中
        bb = cbv.getBoundingBox();    //得到包围盒
        boundingBoxGeode = createBoundingBox(bb);    //Group的几何节点指针boundingBoxGeode
        gantrans->addChild(ganPAT.get());
        root->addChild(boundingBoxGeode.get());    //得到boundingBoxGeode的参数传到根节点中
        root->addChild(gantrans.get());    //将testGroup节点的参数传到根节点root下


        osg::ref_ptr<osg::MatrixTransform> zaw1 = new osg::MatrixTransform;
        zaw1->setMatrix(osg::Matrix::translate(50.0f,0.0f,100.0f));
        zaw1->addChild(osgDB::readNodeFile("zaw1.IVE"));

               
        osg::ref_ptr<osg::MatrixTransform> zaw2 = new osg::MatrixTransform;
        zaw2->setMatrix(osg::Matrix::translate(150.0f,0.0f,40.0f));
        zaw2->addChild(osgDB::readNodeFile("zaw2.IVE"));

        osg::ref_ptr<osg::MatrixTransform> zaw3 = new osg::MatrixTransform;
        zaw3->setMatrix(osg::Matrix::translate(-50.0f,0.0f,100.0f));
        zaw3->addChild(osgDB::readNodeFile("zaw3.IVE"));

        osg::ref_ptr<osg::MatrixTransform> zaw4 = new osg::MatrixTransform;
        zaw4->setMatrix(osg::Matrix::translate(200.0f,0.0f,200.0f));
        zaw4->addChild(osgDB::readNodeFile("zaw3.IVE"));



        osg::AnimationPath* path1 = createpath1();                              
        path1->setLoopMode(osg::AnimationPath::NO_LOOPING);

        //将包围盒的MT节点与运动关联起来
        gantrans->setUpdateCallback(new osg::AnimationPathCallback(path1));
        gantrans->dirtyBound();    //更新testGroup



       
        osg::ref_ptr<osg::Node> axes = new osg::Node;
        axes = osgDB::readNodeFile("axes.osg");
        //osg::ref_ptr<osg::Group> root =new osg::Group;
        root->addChild(gan.get());
        root->addChild(axes.get());
        root->addChild(zaw1.get());
        root->addChild(zaw2.get());
        root->addChild(zaw3.get());
        root->addChild(zaw4.get());

        //申请一个viewer,将root放入。
        osgViewer::Viewer viewer;
        viewer.setSceneData(root.get());
        return viewer.run();
}

zaw3.IVE

1.66 KB, 下载次数: 175, 下载积分: 威望 1

zaw2.IVE

1.66 KB, 下载次数: 152, 下载积分: 威望 1

zaw1.IVE

1.66 KB, 下载次数: 161, 下载积分: 威望 1

gan.IVE

16.01 KB, 下载次数: 156, 下载积分: 威望 1

该用户从未签到

发表于 2011-12-12 17:07:18 | 显示全部楼层
root->addChild(boundingBoxGeode.get());    //得到boundingBoxGeode的参数传到根节点中

你把包围盒节点加在了root下,而root没有受到path动画的作用,因此无法动弹

该用户从未签到

 楼主| 发表于 2011-12-12 18:47:42 | 显示全部楼层
fenma3422 发表于 2011-12-12 17:07
你把包围盒节点加在了root下,而root没有受到path动画的作用,因此无法动弹

谢谢大侠啊 ~~果然搞定 ~~当杆任意移动的话该包围盒就变成OBB的形式了吧?我准备用“gan”和“zaw”进行碰撞检测的,不知道下一步该怎么做,用到什么语句啊?谢谢您了~!~!

该用户从未签到

发表于 2011-12-12 20:34:50 | 显示全部楼层
你需要obb和obb之间的碰撞监测?那么你需要转换到同一坐标系内,然后用几何算法求交,可以参看计算机图形学几何工具算法详解这本书中的相关章节

该用户从未签到

 楼主| 发表于 2011-12-12 21:04:18 | 显示全部楼层
fenma3422 发表于 2011-12-12 20:34
你需要obb和obb之间的碰撞监测?那么你需要转换到同一坐标系内,然后用几何算法求交,可以参看计算机图形学 ...

好的,谢谢您的耐心指导哈~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表