VR_user_happy 发表于 2013-6-4 18:18:16

挖掘机动画

本帖最后由 VR_user_happy 于 2013-6-4 18:37 编辑

刚用OSG的动画路径,结合帧动画实现了一个简单的挖掘机动画,大约用了4天时间,还比较粗糙!哈哈



欢迎喷水!

xiyatuyun 发表于 2013-7-9 10:43:09

内容很丰富,功能比较全:)

VR_user_happy 发表于 2013-6-5 18:00:26

本帖最后由 VR_user_happy 于 2013-6-5 18:39 编辑

这个是带回转的

VR_user_happy 发表于 2013-6-5 18:46:35

这个是运动中的

VR_user_happy 发表于 2013-6-22 13:37:33

本帖最后由 VR_user_happy 于 2013-6-22 13:45 编辑

履带动画:
   


履带动画制作
(类似的动画路径,如传送带等等)
1.创建动画路径
2.创建结构履带片单元(关联动画路径)
3.创建履带链(所有链节关联动画路径)
4.添加父节点group
5.添加Transform节点

就可以任意方位,任意范围缩放、旋转、放置location

如此类推:
可以做出许多的类似的动画路径效果!

1162810317 发表于 2013-6-23 09:50:35

厉害厉害,顶一下,挺感兴趣的,早就想弄了,不知能否加你q讨论,我的q:1033190577

VR_user_happy 发表于 2013-6-23 13:53:13

重点:
   理论建模:(关键点)
   1.直线段部分设置为单元的整数倍
   2.曲线变化点(直线变圆曲线为起点,圆曲线到直线为终点),划分角度为单元整片的几个单元旋转;(这里是关键)
   3.计算直线段的控制点及时间
    4.计算曲线点的dAngle变化转角,及坐标,时间
    5.生成动画路径
   6.单元片关联该动画路径
   7.所有单元片关联同一轨迹,不同控制点
   8.模型匹配单元链节(长度控制)
就 完成了关键操作了

VR_user_happy 发表于 2013-6-27 17:56:16

动画路径时间控制:
停停走走


1.注意动态生成临时路径:
2.控制帧事件中的时间(重点);
3.控制触发条件:(重点)
    加载临时动态路径路径;
4.加载变化后的更新回调。

   可以在任何时候开启触发开关,实现动画的实时调用!

VR_user_happy 发表于 2013-6-27 20:08:04

再看路径变化:


路径变化不影响控制

icing 发表于 2013-6-28 14:22:53

挺不错的哦,欣赏

zuohuaijun 发表于 2013-6-28 14:40:02

不错不错!!!!

VR_user_happy 发表于 2013-7-2 17:55:56

这个是汽车轮子旋转的帧动画:
   

做成帧动画后,生成动画控制管理后,再把节点,加载到其他父节点上,作为子节点附着,车就可以沿路径动画到处跑了。
沿固定路径的路径动画


VR_user_happy 发表于 2013-7-9 17:30:25

再给大家OSG展示帧动画:
   机器人腿部行走动画


VR_user_happy 发表于 2013-7-9 21:15:54

osg 骨骼帧动画:
   机器人行走动画
   
制作帧动画,动作设置的关键帧参数保存为文件形式
用读取关键帧参数文件的形式实现每个支解动作,更灵活。
最后合成一个整体
   整体就可按运动路径自由行走了

VR_user_happy 发表于 2013-7-10 18:09:23

骨骼动画osgCal示例+osgCal编译(yuanloo 发表于 2012-4-11 14:46:17 )

经过近三天的纠结,终于将《OpenSceneGraph三维渲染引擎编程指南》中带有的骨骼动画osgCal示例运行成功。写篇总结纪念这逝去的三天,同时给各位童鞋做个参考,希望大家少走弯路。
首先对Cal3D做一个简单地介绍。Cal3D是一个开源的骨骼动画引擎,它是基于关键帧的骨骼动画,数据文件分为骨骼(Skeleton)、网格(Mesh)和动画(Animation)3个部分,由一个文本文件管理(cal3d.cfg),可以定义多个动作,但每个动画文件是相互独立的。它同时支持动作混合,即可以同时实现两个独立的动作协同一起。其中,每一个动作都有一个权重,即不同的动作优先级是不一样的,通常来说,运动类动作优先级会高于循环类动画。因此,它在渲染过程中的效果是比较好的,管理也是很方便,可以通过修改文本配置文件(.cfg)来管理动画制作信息。
1. 运行环境:win7+X86+vs2008(这是我机器的运行环境,只供参考)
2. 硬件要求:
2.1 CMake-2.8.7(可以直接去官方下载安装版的CMake,只需一步next就可以轻易安装,下载地址: http://www.cmake.org/cmake/resources/software.html )
2.2 SVN源码下载工具。这是一个非常常见的源码下载工具,很多开源的网站就直接提供svn链接,就可以轻易获取最新版本的源码;很多中小型软件开发团队也是会用到该工具,用于代码的上传更新,下载共享,实现多人维护代码。下载地址: http://tortoisesvn.net/
相关使用的教程:
http://dev.baidu.com/wiki/app/index.php?title=SVN%E6%95%99%E7%A8%8B#.E6.96.B0.E5.A2.9E.E6.96.87.E4.BB.B6.E5.92.8C.E7.9B.AE.E5.BD.95
2.3 编译好的osg(我用的是OpenSceneGraph-2.8.2,虽然版本稍微有点老,但是不影响正常的使用,也就无所谓了。现在最新版本是,可以去中国官网下载:http://www.osgchina.org/projects/osgcn/wiki.php )
OSG编译的教程:http://hi.baidu.com/kdlichao/blog/item/18852ad5d7cd95249a502702.html
2.4 编译好的Cal3D。
2.5 编译好的osgCal。
(下面将详细讲解Cal3D和osgCal的编译。)
3. 编译Cal3D,目的就是得到cal3d_d.lib、cal3d_d.dll及cal3d.lib,cal3d.dll,后面编译osgCal依赖cal3d库文件(本例中只用到库文件,动态库只是附属物)。
cal3d源码获取,通过SVN获取最新的源码,最新源码下载地址:
http://svn.gna.org/svn/cal3d/trunk 。
下载的源码文件包含以下三个文件夹


打开cal3d,找到cal3d.sln,打开该工程,包含以下12个工程,


这里我们只需要build Cal3D工程,选择该工程,右击,在弹出框中选中build,单击。等待几分钟就可以在bin文件下的Debug和Releas得到cal3d_d.lib、cal3d_d.dll(debug模式)及cal3d.lib、cal3d.dll(release模式)。
在cal3d目录下新建lib、include文件夹,将cal3d_d.dll、cal3d.dll拷贝到bin文件;cal3d_d.lib、cal3d.lib拷贝到lib文件夹;将src的所以文件拷贝到include文件夹。
可以依据需要编译其他工程,如果编译


max(maya)的cal3d导出插件,那么需要安装max(maya)软件,并且在Tools-Options-Projects and Solutions-C++ Directories的包含文件添加max(maya)安装目录下的include路径,库文件添加对应的lib路径。其他的例子工程可以随便build了,但是我没有明白这些例子工程到底是干啥用的,留着以后探讨吧。
到这里编译osgCal的准备工作就完成了。
4. 编译osgCal,编译osgCal就是为了得到osgCald.dll、osgCald.lib及osgCal.dll、osgCal.lib(后面带d的是在dubeg模式下得到的,不带的是release模式)。
svn获取最新源码,最新源码获取地址:
https://osgcal.svn.sourceforge.net/svnroot/osgcal/trunk/osgCal 及
https://osgcal.svn.sourceforge.net/svnroot/osgcal/trunk/models
(本示例中只用到osgCal,模型models没有用到,具体实现什么功能,目前没有整明白)
打开Cmake,生成osgCal解决方案。
将osgCal文件下的CMakeLists.txt拖到CMake 2.8.7。
点击Configure,选择编译的环境


安装下面的要求,配置参数。


这是重点,一不小心,就在载在这里了!!
这里的include路径及lib文件几乎都是手动加过去的。
对几个重要的参数作个解释:
CAL3D_INCLUDE_DIR      cal3d的include文件的路径(E:/cal3d/cal3d/include)
CAL3D_      LIBRARY          cal3d的lib文件(E:/cal3d/cal3d/lib/cal3d_d.lib)
OPEN_THREADS_INCLUDE_DIR
OpenThreads的include路径
(D:/osgSDK/OpenSceneGraph-2.8.2/include/OpenThreads)
OPEN_THREADS_LIBTARY
OpenThreads的lib路径(D:/osgSDK/OpenSceneGraph-2.8.2/lib/OpenThreads)
OSG_INCLUDE_DIR         
osg的include文件路径(D:/osgSDK/OpenSceneGraph-2.8.2/include)
OSG_LIBRARY            
osg的lib文件(D:/osgSDK/OpenSceneGraph-2.8.2/lib/osg.lib)
根据SDK所在的位置指定正确的路径。
参数配置完毕后,第二次点击configure。
确定无误后点击Generate,显示Configuring done,表明配置成功,将生成解决方案。
注意:这里include及lib路径要与osgCal工程下的Tools-Options-Projects and Solutions-C++ Directories的include及lib路径相一致。要是在CMake中未添加这些include及lib路径(前提是Generating done),在工程中再添加include及lib路径也是可以的。Cmake中允许有警告,但是不要有错误,否则编译会通不过去。
打开osgCal.sln解决方案,


注意:检查Tools-Options-Projects and Solutions-C++ Directories中的include及lib路径是否正确。
Build ALL_BUILD。等待十几分钟,显示6 succeeded,0 faild,表明编译成功。
将osgCald.dll、osgCal.dll拷贝到bin文件;osgCald.lib、osgCal.lib拷贝到lib文件夹。
经过千辛万苦,终于得到了所需要的osgCald.dll、osgCal.dll及osgCald.lib、osgCal.lib。下面可以开始跑例子了,检验一下生成的库文件及动态库是否正确。
5. 配置osgCal环境,运行osgCal骨骼示例。
开始-控制面板-系统和安全-系统-高级系统设置-高级-环境变量-用户变量-PATH添加osgCald.dll、osgCal.dll的路径。


新建工程win32控制台工程,工程命名skeleton,将代码粘贴至skeleton.cpp。代码下载地址:
http://read.pudn.com/downloads156/sourcecode/windows/opengl/695085/Cal3D%E5%8A%A8%E7%94%BB%E7%9A%84%E5%8A%A0%E8%BD%BD%E3%80%81%E6%98%BE%E7%A4%BA%E5%8F%8A%E6%8E%A7%E5%88%B6%E7%A4%BA%E4%BE%8B/osgVR/main.cpp__.htm
骨骼模型下载地址:
http://ftp.jaist.ac.jp/pub/sourceforge/o/project/os/osgcal/test_models/0.0.1/
Tools-Options-Projects and Solutions-C++ Directories添加osgCal的include及bin路径。
Project-Properties-Configuration Properties-Linker-Input-Additional添加依赖库
osg.lib
osgDB.lib
osgGA.lib
osgUtil.lib
osgViewer.lib
osgCal.lib
这里选择的是Release模式。
编译工程,运行。将会展示如下的


示例的骨骼动画是非常生动的。有以下几种模式:
animation=skeleton_idle.caf
animation=skeleton_strut.caf
animation=skeleton_walk.caf
animation=skeleton_jog.caf
animation=skeleton_wave.caf
animation=skeleton_shoot_arrow.caf
animation=skeleton_hiphop.caf

按“1”对应的是idle,按“2”对应的是strut,按“3”对应的是walk,....

好了!我们的osgCal例子运行成功,enjoy!!

最后附上源码:

/**********************************************************
*Write by FlySky
*zzuxp@163.comhttp://www.OsgChina.org   
**********************************************************/   

#include <osgViewer/Viewer>   
#include <osgViewer/ViewerEventHandlers>   

#include <osg/Node>   
#include <osg/Geode>   
#include <osg/Geometry>   
#include <osg/Group>   

#include <osgDB/ReadFile>   
#include <osgDB/WriteFile>   

#include <osgGA/TrackballManipulator>   
#include <osg/BoundingSphere>   
#include <osgUtil/Optimizer>   

#include <osgCal/CoreModel>   
#include <osgCal/Model>   

#include <iostream>   

//加载模型   
osg::Node* makeModel( osgCal::CoreModel* cm,osgCal::BasicMeshAdder* ma, int animNum = -1 )   
{   
      osgCal::Model* model = new osgCal::Model();   

      //从CoreModel中创建模型   
      model->load( cm, ma );   

      if ( animNum != -1 )   
      {   
                //实现动画   
                model->blendCycle( animNum, 1.0f, 0 );   
      }   

      return model;   
}   

//动画控制事件处理器   
class AnimationToggleHandler : public osgGA::GUIEventHandler   
{   
public:   
      //构造函数   
      AnimationToggleHandler( osgCal::Model* m,   
                const std::vector <std::string >& an )   
                : model( m )   
                , animationNames( an )   
                , currentAnimation( -1 )   
      {   
                //   
      }   
      //事件处理函数   
      bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)   
      {   
                osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);   
                if (!viewer) return false;   

                switch(ea.getEventType())   
                {   
                case(osgGA::GUIEventAdapter::KEYDOWN):   
                        {   
                              if ( ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL )   
                              {   
                                        if ( ea.getKey() >= '1' &&   
                                                ea.getKey() < '1' + (int)animationNames.size() )   
                                        {   
                                                //执行动作   
                                                model->executeAction( ea.getKey()- '1' );   
                                        }   
                              }   
                              else if ( ea.getKey() >= '1' &&   
                                        ea.getKey() < '1' + (int)animationNames.size() )   
                              {      
                                        //重新初始化   
                                        if ( currentAnimation != -1 )   
                                        {   
                                                model->clearCycle( currentAnimation, 1.0 );   
                                        }   

                                        currentAnimation = ea.getKey() - '1';   
                                        //循环动作   
                                        model->blendCycle(currentAnimation, 1.0f, 1.0 );                           
                              }   
                              //清除当前动作,重置初始动作   
                              else if ( ea.getKey() == '0' )   
                              {   
                                        model->clearCycle( currentAnimation, 0.0 );   

                                        currentAnimation = -1;   
                              }   
                        }   
                default: break;   
                }   

                return false;   
      }   

private:   
      //动画模型   
      osgCal::Model*            model;   
      //动画动作名称   
      std::vector <std::string >animationNames;   
      //当前动作   
      int                         currentAnimation;   

};   

//暂停或者渲染状态切换事件处理器   
class ToggleHandler : public osgGA::GUIEventHandler   
{   
public:   

      ToggleHandler( bool& toggleVar,charkey):   
          toggleVar( &toggleVar ),   
                  key( key )   
          {   
                  //   
          }   
          //事件处理函数   
          bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)   
          {   
                  osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);   
                  if (!viewer) return false;   

                  switch(ea.getEventType())   
                  {   
                  case(osgGA::GUIEventAdapter::KEYDOWN):   
                        {   
                                  if ( ea.getKey() == key )   
                                  {   
                                          //切换状态   
                                          *toggleVar = !(*toggleVar);   
                                  }   
                        }   
                  default: break;   
                  }   

                  return false;   
          }   

private:   
      //当前状态   
      bool*       toggleVar;   
      //按键   
      char      key;   
};   

int main()   
{   
      //创建场景浏览器   
      osgViewer::Viewer* viewer = new osgViewer::Viewer();   

      osg::Group* root = new osg::Group();   

      //一系列动作名   
      std::vector <std::string > animationNames;   
      //动画模型名   
      std::string fn("E:\\OSG\\osgCalByflySky\\test_models\\thug\\cal3d.cfg");   //skeleton\\skeleton hero\\hero
      //初始化静止模型动作   
      int animNum = -1;   

      //动画模型   
      osgCal::CoreModel* coreModel = new osgCal::CoreModel();   

      //基本网格   
      osgCal::BasicMeshAdder* meshAdder= new osgCal:efaultMeshAdder ();   

      //网格参数   
      osgCal::MeshParameters* p = new osgCal::MeshParameters();   
      //采用深度,用于减少子网被遮盖的不可见的像素   
      p->useDepthFirstMesh = true ;   
      //平滑模式   
      p->software = true ;   

      //加载外部模型文件   
      coreModel->load( fn, p);   

      //添加模型   
      root->addChild( makeModel( coreModel,meshAdder,animNum ) );   

      //得到一系列动作名称   
      animationNames = coreModel->getAnimationNames();   

      //动作切换控制   
      viewer->addEventHandler( new AnimationToggleHandler( (osgCal::Model*)root->getChild(0), animationNames ) );   

      //暂停控制   
      bool paused = false;   
      viewer->addEventHandler( new ToggleHandler( paused, 'p' ) );   

      //优化场景数据   
      osgUtil::Optimizer optimizer ;   
      optimizer.optimize(root);   

      viewer->setSceneData(root);   

      viewer->setCameraManipulator(new osgGA::TrackballManipulator());   

      viewer->realize();   

      //添加时间控制   
      osg::Timer_t startTick = osg::Timer::instance()->tick();   

      //初始化一个状态枚举变量,控制暂停或者渲染   
      //默认为渲染状态   
      enum PauseState { Unpaused, Paused };   
      PauseState   pauseState = Unpaused;   
      osg::Timer_t pauseStartTick = 0;   
      double       totalPauseTime = 0;   

      //通过控制当前帧显示时间,来控制是否暂停或者渲染   
      while ( !viewer->done() )   
      {   
                osg::Timer_t tick = osg::Timer::instance()->tick();   

                //暂停   
                if ( pauseState == Unpaused && paused )   
                {   
                        pauseState = Paused;   
                        pauseStartTick = tick;   
                }   
                //渲染   
                if ( pauseState == Paused && !paused )   
                {   
                        pauseState = Unpaused;   
                        //得到暂停时间   
                        totalPauseTime += osg::Timer::instance()->delta_s( pauseStartTick, tick );   
                }   

                //当前时间   
                double currentTime = osg::Timer::instance()->delta_s(   
                        startTick,   
                        pauseState == Unpaused ? tick : pauseStartTick );   

                //继续暂停帧开始渲染   
                viewer->frame( currentTime - totalPauseTime );   
      }   

      return 0;   
}

VR_user_happy 发表于 2013-7-10 18:16:52

看osg 中调用osgcal插件后执行的Cal3D动画
1.行走


2.跑动

VR_user_happy 发表于 2013-7-24 12:51:42

本帖最后由 VR_user_happy 于 2013-7-24 12:53 编辑

挖掘机臂的组合动画



1.使用时间线控制管理
2.用文件参数控制生成分解动作;
    文件控制:骨骼节点的连接点、旋转轴、旋转角度等;
3.保持骨骼的一致性,包括初始位姿,和帧更新位置;
4.用文件控制读取每个动作的帧播放进出时间,并生产时间片对象;
5.生产的动画节点保持不变性,并最终添加到场景节点任意位置;

VR_user_happy 发表于 2013-7-25 17:37:46

本帖最后由 VR_user_happy 于 2013-7-25 17:41 编辑

使用OSG 的帧骨骼动画、加时间线动画控制实现:
机器人行走、站立、跑动组合动画(以后加载路径,动画路径的运行时间控制,与动作设置的起止时间相协调,就可看到整个运动状态了。)
目前先以相对坐标系为参考模拟:



本人初次尝试,对人体的运动规律不是很了解,所以就假定了一些运动状态作为其中的状态机,作为模拟的对象, 所以运动画面的肢体配合不是很理想,单亦可以完成分解动作的组合连续了。
1.各个肢体(手臂、腿)均由独立的文件控制骨骼动画动作;
2.各个骨骼的分解状态机由独立的帧参数文件控制,用以模拟走路、跑动等状态的状态机;
3.

VR_user_happy 发表于 2013-7-26 09:59:54


机器人行走、站立、跑动组合动画:(osg骨骼帧时间线动画、加路径动画)
这次加上路径看机器人的组合动作

gameaaa 发表于 2013-7-26 10:24:20

履带那种东西其实可以用更简单的方法来弄:D

VR_user_happy 发表于 2013-7-26 10:35:06

谢谢,可以提供思路!
我的目地就是先抛出个方案,希望大家集思广益,丰富OSG的动画实现!

VR_user_happy 发表于 2013-7-29 16:54:48

再给大家展示龙卷风模拟路径动画:


主要是对龙卷风数学模型的抽象,纯数学理论计算了,现只用线段的形式表现,看以后能否用粒子系统表达

VR_user_happy 发表于 2013-7-29 17:23:51

本帖最后由 VR_user_happy 于 2013-7-29 17:35 编辑

用粒子点云的方式表达效果如下:



如果采样点不能太多,否则系统就出现跳帧现象

这个效果好点:



天行剑 发表于 2013-8-15 00:15:30

VR_user_happy 发表于 2013-6-5 18:46 static/image/common/back.gif
这个是运动中的

请问履带运动效果也是在3ds max里面制作好然后用Cal3d导出在osg中使用吗?

VR_user_happy 发表于 2013-8-15 09:19:07

我的履带动画效果:纯粹是用OSG 自带的动画路径实现的!
用OSG实现的好处是:
你可以随意控制节点,播放时间等等!
而且可以锻炼你对OSG的动画路径的理解!

当然,你也可不妨试试用Cal3d导出到OSG中,但控制就会有很大的难度!

天行剑 发表于 2013-8-22 00:32:30

VR_user_happy 发表于 2013-8-15 09:19 static/image/common/back.gif
我的履带动画效果:纯粹是用OSG 自带的动画路径实现的!
用OSG实现的好处是:
你可以随意控制节点,播 ...

cal3d我尝试过了,vs2010的编译通不过,而且据array大神所说,这个已经停止更新了,只好放弃……
osg自带的动画路径如何实现履带动画呢?我在论坛里面发帖咨询过履带动画(http://bbs.osgchina.org/forum.php?mod=viewthread&tid=10929),可还是不会做,很想请教您这个履带动画的详细步骤啊,能否讲讲呢?

VR_user_happy 发表于 2013-8-22 09:49:12

【1】.建立履带路径轨迹曲线(直线段公式,曲线段公式)
    1.设置采样控制点(粗略),为初始化化一个完整的履带做铺
       ( 假定一个一个链节的组装)
   2.再细化控制点,使自动线性差分计算更符合运动;
      (加密运动曲线的轨迹控制点)

(关键点)
   1.直线段部分设置为单元的整数倍
   2.曲线变化点(直线变圆曲线为起点,圆曲线到直线为终点),划分角度为单元整片的几个单元旋转;(这里是关键)
   3.计算直线段的控制点及时间
   4.计算曲线点的dAngle变化转角,及坐标,时间
【2】生成动画路径
   1.单元片关联该动画路径
   2.所有单元片关联同一轨迹,不同控制点作为起点
【3】.模型匹配单元链节(长度控制)
1.调整比例使连接匹配一个控制链节
【4】
    模型与动画路径关联
    完成了关键操作了

VR_user_happy 发表于 2013-8-22 09:54:15

另外,我的机器配置就是OSG3.01+VS2010+Cal3D
按上面介绍的编译,只编译RELEASE版是可用的,你多尝试,才会搞清楚OSG使用插件的机制,和CMAKE之间的关系!

天行剑 发表于 2013-8-22 12:57:46

VR_user_happy 发表于 2013-8-22 09:54 static/image/common/back.gif
另外,我的机器配置就是OSG3.01+VS2010+Cal3D
按上面介绍的编译,只编译RELEASE版是可用的,你多尝试,才会 ...

好的 太感谢了 我再琢磨琢磨 下次还得向您请教啊
O(∩_∩)O~

天行剑 发表于 2013-8-27 12:50:33

你好!做履带动画遇到难题了,还得请教你呢
目前我把履带路径做好了,然后放入一个物体能够沿着履带路径循环运动。但是整条履带是由上百个小长方体组成的,如何才能把他们首尾相连放置到路径的每个点位上呢?
页: [1] 2 3
查看完整版本: 挖掘机动画