65.9K
CodeProject 正在变化。 阅读更多。
Home

OSG 的 XML 解析器(支持 Qt)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (6投票s)

2012 年 12 月 24 日

CPOL

4分钟阅读

viewsIcon

16738

downloadIcon

1162

用于在 OSG 3D 引擎中创建场景的简单 XML 解析器

下载 OSGXML.zip

引言

在我的项目中,需要一个3D引擎来可视化具有3D内容的场景。因此,我需要一个简单的3D引擎,它在使用时没有版权问题,并且对代码有开源策略。我选择了 Open Scene Graph 3D 引擎。这是一个广为人知的3D引擎,拥有广泛的社区支持,允许直接调用 OpenGL 命令。然而,我遇到了一些问题。其中最大的问题是只能直接在 C++ 代码中编译场景。我认为,为每个场景制作单独的 dll 或 exe 文件毫无意义。我决定,最好制作一个特殊的 XML 解析器,可以通过简单的语义快速构建3D场景。

背景

在我的项目中使用 Qt 框架 4.8.4。使用 Qt 有两个主要原因。

首先,我需要一种简单的方法来控制动画和代码的控制可能性。Qt 允许在脚本中使用 C++ 类。核心 QScript 支持调用 C++ 类的函数,并为控制 OSG 场景的状态提供了一种简单的方法。

第二个原因是 OSG 没有音频系统。我使用 ffmpeg 编译了 OSG 3.1.3 版本,但它只允许播放没有音频支持的视频流。经过一些研究,我决定使用 QMultimedia 来播放视频文件的环绕声音频。这种方法与广泛的计算机平台兼容。

我制作了一个软件,允许以简单的方式创建3D场景。

使用代码

这个 XML 解析器包含 27 个类,展示所有类毫无意义。Qt 的原始代码可以从 下载 OSGXML.zip 下载。我只想介绍用于描述 OSG 场景的 XML 结构。它包括以下节点

Group - 用于分组场景元素。

MatrixTransform - 用于对场景元素进行分组,并对组应用矩阵变换。

Switch - 用于对场景元素进行分组,并控制元素的显示和隐藏。

Model - 用于下载 3d 模型。我更喜欢使用 .fbx 格式。它可以支持模型的动画。

ImageSurface - 用于在 3D 空间中可视化图像。

简单的 XML 结构显示在下一个列表

<?xml version="1.0" encoding="utf-8"?>
<OSGStructure xmlns="">
  <OSGStructure.Scripts>
  <Script Path="Script1.js"/> 
 </OSGStructure.Scripts>  
    <Group>
    <MatrixTransform >
 <MatrixTransform.SetMatrix>
 
  <Rotate Parametr="{ Angle=90, Axis=X, Option=Quat}"/>
 
  <Translate X="0.0" Y="0.0" Z="0.0001"/>
 
 </MatrixTransform.SetMatrix>
 
 <Model Name="Four" Path="raymen/raymen.fbx" Scale="0.05">
  <Model.Animation>
   <AnimationManager Name="Four_Animation" PlayMode="ONCE"/>
  </Model.Animation>
 
  <Model.SetTriggers>
 
   <KeyTrigger Name="Start_Four_Animation" Key="KEY_Space" />
 
  </Model.SetTriggers>
 
  <Model.SetResources>
 
   <AudioPlayer Name="Character" Path="Character.wav" />
 
  </Model.SetResources>
 </Model>
    </MatrixTransform>
    </Group>
</OSGStructure>

在这个 XML 代码中, MatrixTransform.SetMatrix 是用于通过 RotateTransform Scale 设置矩阵的节点。 Model.Animation 允许设置 AnimationManager 以解析原始模型并控制动画。 Model.SetTriggers 允许设置触发器,用于诸如按下键盘上的键或移动鼠标之类的事件。目前,我只创建了 KeyTrigger,但它可以扩展到鼠标或触摸(对于 Android)。 Model.SetResources 用于包含非视觉元素,例如 AudioPlayerOSGStructure.Scripts 包含 Script。脚本用于整个场景。每个场景可以使用多个脚本。当然,这些脚本对于实时游戏来说执行速度较慢,但它们很简单,并且适用于场景的可视化。 脚本可以具有以下列表

function StartAnimation()
{
    Four.Four_Animation.playAnimation();
}
 
function StartAudio()
{
    Four.Character.stop();
 
    Four.Character.play();
 
}
 
Four.Start_Four_Animation.keyDown.connect(StartAnimation);
 
Four.Start_Four_Animation.keyDown.connect(StartAudio);

在这个脚本中,Four 是 OSG 场景的命名元素。它有一个子触发器 Start_Four_Animation,它会发出信号 keyDown. 这个信号与两个函数绑定。在这些函数中,执行 Four.Four_Animation.playAnimation() Four.Character.play() ,它们启动动画并播放音轨。

下一个列表显示了 ImageSurface 的用法和纹理的绑定。

<ImageSurface Visible="false" Name="Video1" Stretch="{Type=Uniform, TargetName=VideoPlayer}">
 
 <ImageSurface.Textures>
      <Texture2D  Path="1.tga" />
        </ImageSurface.Textures>
 
</ImageSurface>

此代码可以通过 VideoTexture 修改为使用视频文件

 <ImageSurface.Textures>
      <VideoTexture Name="VideoPlayer" Path="Making.avi" />
 </ImageSurface.Textures>
 
 <ImageSurface.SetTriggers>
 
  <KeyTrigger Name="Play_Pause" Key="KEY_P" />
 
  <KeyTrigger Name="Stop" Key="KEY_R" />
 
 </ImageSurface.SetTriggers>

此代码支持多重纹理,可以表示为

 <ImageSurface.Textures>
      <Texture2D  Path="1.tga" />
 
 <Texture2D Path="2.tga" />
 
 </ImageSurface.Textures>
 

 <ImageSurface.Textures>
      <Texture2D  Path="1.tga" />
     <VideoTexture Name="VideoPlayer" Path="Making.avi" />
 
 </ImageSurface.Textures>
 

 <ImageSurface.Textures>
      <VideoTexture Name="VideoPlayer1" Path="Making.avi" />
 <VideoTexture Name="VideoPlayer2" Path="01.mp4" />
 
 </ImageSurface.Textures>

这种应用纹理的方法可以与模型一起使用,并且这些纹理可以应用于模型的特定网格或场景。为此,属性 TargetMesh 用于定位特定网格。这种方法可以用于将 VideoTexture 应用于网格。

<pre lang="C++"><Model Name="Four" Path="raymen/raymen.fbx" Scale="0.05">
 <Model.Animation>
  <AnimationManager Name="Four_Animation" PlayMode="ONCE"/>
 </Model.Animation>
 
 <Model.SetTriggers>
 
  <KeyTrigger Name="Start_Four_Animation" Key="KEY_Space" />
 
 </Model.SetTriggers>
 
 <Model.SetResources>
 
  <AudioPlayer Name="Character" Path="Character.wav" />
 </Model.SetResources>
 
 <Model.Textures>
  <VideoTexture TargetMesh="Mesh_Rayman3_Rayman_3" Name="VideoPlayer" Path="Making.avi" /> 
 </Model.Textures>
 
</Model>

Switch 中显示和隐藏元素是通过应用属性 Visible="false" 或在脚本中调用函数 setStateNode 完成的

XML 文件示例及其预览可以通过此链接下载 OSGXML-Examples

关注点

该项目是为增强现实产品开发的,但一些解决方案可以单独使用。例如,从 ffmpeg 播放视频或播放模型的动画。此 XML 解析器的可能性非常有限,但我希望它可以在使用 OSG 的过程中帮助某人。增强现实的演示版本可以通过此链接下载 OSGAR

© . All rights reserved.