美国海军(NPS)的OSG教程

美国海军(NPS)的OSG教程
美国海军(NPS)的OSG教程

美国海军(NPS)的OSG教程

第一课OpenSceneGraph几何体的绘制 (2)

第二课使用StateSet创建带有纹理的几何体 (5)

第三课使用内嵌几何形状(Shape)对象,改变渲染状态 (8)

第四课StateSet的工作流程 (9)

第五课从文件加载模型并放置在场景中 (11)

第六课osgText,抬头显示(HUD),渲染元(RenderBin) (13)

第七课搜索并控制开关节点和DOF(自由度)节点 (16)

第八课使用更新回调来更改模型 (22)

第九课第一节处理键盘输入 (25)

第九课第二节处理键盘输入实现更新回调 (28)

第十课第一节使用自定义矩阵来放置相机 (31)

第十课第二节实现跟随节点的相机 (33)

第十课第三节环绕(始终指向)场景中节点的相机 (37)

第十课第四节如何获取节点在世界坐标的位置 (39)

第十一课第一节使用两个独立的摄像机浏览场景 (41)

第十一课第二节使用多个独立的摄像机观察场景(基于OSG 1.2版本) (46)

第十二课第一节使用OpenGL顶点着色器和片元着色器 (51)

第十二课第二节向着色器传递变量数据 (53)

第十二课第三节更新着色器 (55)

第十二课第四节如何快速实现渐灰效果 (58)

第十四课交集测试 (63)

第十五课第一节向场景中添加osgParticle粒子效果 (68)

第十五课第二节粒子系统的保存以及读取 (72)

第十六课第一节节点遮掩概述(基于OSG 1.2版本) (73)

第十六课第二节节点遮掩示例(基于OSG 1.2版本) (75)

第一课OpenSceneGraph几何体的绘制

本章将介绍一些创建几何体元素的方法。通常我们有这样几种处理几何体的手段:底层手段是使用松散封装的OpenGL基元;中级手段是使用 OpenSceneGraph的基本几何体;高级手段是从文件读入模型。本章教程将主要介绍底层手段的实现方法。这种实现具有很强的灵活性,相应的工作量也比较大。应用于场景图形级别的几何体通常是从文件读入的,因而顶点的跟踪和处理工作将由文件读取插件完成。

背景?

下面将对几个常用的类作简要的介绍:

Geode类

Geode类派生自Node节点类。节点类(包括Geode)可以作为场景图形的叶节点添加。Geode类的实例可以与任意多个可绘制对象Drawable类相关联。

Drawable类

作为可绘制对象基类的Drawable类是一个纯虚类,它有六个派生类。其中Geometry类中可以直接指定顶点数据,或者指定任意数目的几何基元PrimitiveSet类与其关联。

顶点和顶点属性数据(颜色,法线,纹理坐标)是保存在数组中的。多个顶点可以共享同一种颜色,法线和纹理坐标,同时我们还可以使用索引将顶点数组映射给颜色,法线或纹理坐标的数组。

PrimitiveSet类

这个类松散地封装了OpenGL的绘图基元,包括点(POINTS),线(LINES),多段线(LINE_STRIP),封闭线(LINE_LOOP),四边形(QUADS),多边形(POLYGON)等。

代码?

下面的代码将设置一个用于显示场景的视窗,一个作为场景图形根节点的Group类实例,一个用于记录可绘制对象(Drawable)的几何体节点(Geode),以及一个记录顶点和顶点相关数据的Geometry类实例。本例中我们将渲染一个金字塔的形状。

...

int main()

{

...

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

osg::Geode* pyramidGeode = new osg::Geode();

osg::Geometry* pyramidGeometry = new osg::Geometry();

现在我们将金字塔几何体与Geode关联,并将Geode叶节点添加到场景图形的根节点。

pyramidGeode->addDrawable(pyramidGeometry);

root->addChild(pyramidGeode);

声明一个顶点数组。每个顶点有三个坐标值,也就是一个Vec3类的实例。osg::Vec3Array类的实例可以用来保存顶点数组。它派生自 STL库的vector模板,因此我们可以使用push_back方法向其中追加数组元素。该方法的作用是在向量数组的末尾添加一个元素,因此数组中第一个元素的索引值为0,紧随其后的第二个元素为1,以此类推。

我们使用Z轴向上的右手坐标系作为参照,数组元素0-4用于表达金字塔形体的五个顶点。

osg::Vec3Array* pyramidVertices = new osg::Vec3Array;

pyramidVertices->push_back( osg::Vec3( 0, 0, 0) ); // 左前

pyramidVertices->push_back( osg::Vec3(10, 0, 0) ); // 右前

pyramidVertices->push_back( osg::Vec3(10,10, 0) ); // 右后

pyramidVertices->push_back( osg::Vec3( 0,10, 0) ); // 左后

pyramidVertices->push_back( osg::Vec3( 5, 5,10) ); // 塔尖

将这一顶点集合关联到Geometry实例上,后者已经与场景的Geode叶节点相关联。

pyramidGeometry->setVertexArray( pyramidVertices );

现在我们创建几何基元类PrimitiveSet的实例并添加到金字塔几何体上。金字塔底部的四个点组成一个基面,可以使用DrawElementsUint类来实现。这个类同样继承自STL库的vector模板,我们可以使用push_back顺序向其中添加元素。为了保证背面剔除(backface cullling)的正确,我们需要按照逆时针的顺序添加顶点数据。类的构造函数使用几何基元枚举类型(与OpenGL的几何基元枚举类型相同)作为输入参数,另一个输入参数是作为起始点的顶点索引值。

osg::DrawElementsUInt* pyramidBase =

new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);

pyramidBase->push_back(3);

pyramidBase->push_back(2);

pyramidBase->push_back(1);

pyramidBase->push_back(0);

pyramidGeometry->addPrimitiveSet(pyramidBase);

重复这一过程,添加金字塔的每个面。再次注意,顶点是以逆时针为顺序添加的。

osg::DrawElementsUInt* pyramidFaceOne =

new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);

pyramidFaceOne->push_back(0);

pyramidFaceOne->push_back(1);

pyramidFaceOne->push_back(4);

pyramidGeometry->addPrimitiveSet(pyramidFaceOne);

osg::DrawElementsUInt* pyramidFaceTwo =

new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);

pyramidFaceTwo->push_back(1);

pyramidFaceTwo->push_back(2);

pyramidFaceTwo->push_back(4);

pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);

osg::DrawElementsUInt* pyramidFaceThree =

new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);

pyramidFaceThree->push_back(2);

pyramidFaceThree->push_back(3);

pyramidFaceThree->push_back(4);

pyramidGeometry->addPrimitiveSet(pyramidFaceThree);

osg::DrawElementsUInt* pyramidFaceFour =

new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);

pyramidFaceFour->push_back(3);

pyramidFaceFour->push_back(0);

pyramidFaceFour->push_back(4);

pyramidGeometry->addPrimitiveSet(pyramidFaceFour)

定义一个Vec4的数组,用于保存颜色值。

osg::Vec4Array* colors = new osg::Vec4Array;

colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //索引0 红色

colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) ); //索引1 绿色

colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); //索引2 蓝色

colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) ); //索引3 白色

下一步要将顶点数组的元素与颜色数组的元素对应起来。我们将声明一个与顶点数组有相同个数元素的向量组。它将负责连接各个顶点与颜色。该向量组的索引对应顶点数组的元素,其取值对应颜色数组的索引。如果需要将顶点数组与法线数组或者纹理坐标数组一一对应,那么还需重复这一步骤。

注意在本例中,我们需要将5个顶点对应到4种颜色上。因此顶点数组的元素0(左下)和元素4(塔尖)都需要对应到颜色数组元素0(红色)上。

osg::TemplateIndexArray

*colorIndexArray;

colorIndexArray =

new osg::TemplateIndexArray;

colorIndexArray->push_back(0); // vertex 0 assigned color array element 0

colorIndexArray->push_back(1); // vertex 1 assigned color array element 1

colorIndexArray->push_back(2); // vertex 2 assigned color array element 2

colorIndexArray->push_back(3); // vertex 3 assigned color array element 3

colorIndexArray->push_back(0); // vertex 4 assigned color array element 0

下一步,我们将颜色数组以及刚才创建的颜色索引数组与几何体相关联,并设置绑定模式为“按顶点绑定”。

pyramidGeometry->setColorArray(colors);

pyramidGeometry->setColorIndices(colorIndexArray);

pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

osg::Vec2Array* texcoords = new osg::Vec2Array(5);

(*texcoords)[0].set(0.00f,0.0f);

(*texcoords)[1].set(0.25f,0.0f);

(*texcoords)[2].set(0.50f,0.0f);

(*texcoords)[3].set(0.75f,0.0f);

(*texcoords)[4].set(0.50f,1.0f);

pyramidGeometry->setTexCoordArray(0,texcoords);

现在我们已经创建了一个几何体节点,并将其添加到场景中。其中的几何体是可以复用的,例如,如果我们希望在第一个金字塔右侧15个单位再放置第二个金字塔,那么我们可以将这个Geode节点作为位置变换节点的子节点,并再次添加到场景当中。

//初始化位置变换节点

osg::PositionAttitudeTransform* pyramidTwoXForm =

new osg::PositionAttitudeTransform();

//使用osg::Group的addChild方法,将位置变换节点添加到根节点的子节点上,并将金字塔节点作为变换节点的子节点

root->addChild(pyramidTwoXForm);

pyramidTwoXForm->addChild(pyramidGeode);

// 初始化一个Vec3实例,用于改变模型在场景中的位置

osg::Vec3 pyramidTwoPosition(15,0,0);

pyramidTwoXForm->setPosition( pyramidTwoPosition );

最后,设置视窗类并进入仿真循环。

osgViewer::Viewer viewer;

viewer.setSceneData( root );

viewer.run();

第二课使用StateSet创建带有纹理的几何体

目标:

向使用OpenGL基元绘制的基本几何体添加纹理。

背景?

上一个教程介绍了使用OpenGL基元创建基本几何体并在视窗中浏览的方法。本章将介绍如何向几何体添加纹理。为了使代码易于阅读,我们将有关金字塔绘制的代码封装到一个函数中,并返回一个Geode指针。代码如下所示:

osg::Geode* createPyramid()

{

osg::Geode* pyramidGeode = new osg::Geode();

osg::Geometry* pyramidGeometry = new osg::Geometry();

pyramidGeode->addDrawable(pyramidGeometry);

// 指定顶点

osg::Vec3Array* pyramidVertices = new osg::Vec3Array;

pyramidVertices->push_back( osg::Vec3(0, 0, 0) ); // 左前

pyramidVertices->push_back( osg::Vec3(2, 0, 0) ); // 右前

pyramidVertices->push_back( osg::Vec3(2, 2, 0) ); // 右后

pyramidVertices->push_back( osg::Vec3( 0,2, 0) ); // 左后

pyramidVertices->push_back( osg::Vec3( 1, 1,2) ); // 塔尖

// 将顶点数组关联给几何体

pyramidGeometry->setVertexArray( pyramidVertices );

// 根据底面的四个顶点创建底面四边形(QUAD)

osg::DrawElementsUInt* pyramidBase =

new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);

pyramidBase->push_back(3);

pyramidBase->push_back(2);

pyramidBase->push_back(1);

pyramidBase->push_back(0);

// 创建其他面的代码从略

osg::Vec4Array* colors = new osg::Vec4Array;

colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //索引0 红色

colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) ); //索引1 绿色

colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); //索引2 蓝色

colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) ); //索引3 白色

osg::TemplateIndexArray

*colorIndexArray;

colorIndexArray =

new osg::TemplateIndexArray;

colorIndexArray->push_back(0); // 顶点0对应颜色元素0

colorIndexArray->push_back(1); // 顶点1对应颜色元素1

colorIndexArray->push_back(2); // 顶点2对应颜色元素2

colorIndexArray->push_back(3); // 顶点3对应颜色元素3

colorIndexArray->push_back(0); // 顶点4对应颜色元素0

pyramidGeometry->setColorArray(colors);

pyramidGeometry->setColorIndices(colorIndexArray);

pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

//由于纹理坐标与顶点是一一对应的,因此不需要使用索引数组来进行映射。我们只需要直接使用setTexCoordArray方法即可. setTexCoordArray方法传递osg::Vec2的二维坐标数组作为参数,传递的二维坐标数与顶点数相同。数组中元素的位置与顶点数组中顶点的位置一一对应。

osg::Vec2Array* texcoords = new osg::Vec2Array(5);

(*texcoords)[0].set(0.00f,0.0f); // 顶点0的纹理坐标

(*texcoords)[1].set(0.25f,0.0f); // 顶点1的纹理坐标

(*texcoords)[2].set(0.50f,0.0f); // 顶点2的纹理坐标

(*texcoords)[3].set(0.75f,0.0f); // 顶点3的纹理坐标

(*texcoords)[4].set(0.50f,1.0f); // 顶点4的纹理坐标

pyramidGeometry->setTexCoordArray(0,texcoords);

return pyramidGeode;

}

加载纹理,创建渲染状态类,关联到节点?

我们使用StateSet类来控制几何基元的渲染状态。下面的代码演示了从文件中读取纹理,创建StateSet类并设置纹理,以及关联StateSet到场景节点的方法。代码的前一部分与上一章教程相同。首先我们初始化视窗并创建只有单一金字塔的场景。

int main()

{

// 声明场景的根节点

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

osg::Geode* pyramidGeode = createPyramid();

root->addChild(pyramidGeode);

现在我们添加纹理。我们定义一个纹理实例并设置其数据变更类型为“DYNAMIC”(否则的话,OSG的优化过程中可能会自动去除这个纹理)。纹理类封装了OpenGL纹理模式(GL_TEXTURE_WRAP,GL_TEXTURE_FILTER等),以及一个osg::Image对象。下面的代码将演示如何从文件读入osg::Image实例并将其关联到纹理。

osg::Texture2D* KLN89FaceTexture = new osg::Texture2D;

//避免在优化过程中出错

KLN89FaceTexture->setDataVariance(osg::Object::DYNAMIC);

// 从文件读取图片

osg::Image* klnFace = osgDB::readImageFile("KLN89FaceB.tga");

if (!klnFace)

{

std::cout << " couldn't find texture, quiting." << std::endl;

return -1;

}

// 将图片关联到纹理

KLN89FaceTexture->setImage(klnFace);

Texture类可以关联到渲染状态StateSet类。下一步我们将创建一个StateSet,将纹理关联到这个渲染状态实例并允许使用纹理,最后将StateSet关联到几何体节点上。

// 创建StateSet

osg::StateSet* stateOne = new osg::StateSet();

// 将纹理关联给StateSet的纹理单元0

stateOne->setTextureAttributeAndModes

(0,KLN89FaceTexture,osg::StateAttribute::ON);

// 将渲染状态关联给金字塔节点

pyramidGeode->setStateSet(stateOne);

osgViewer::Viewer viewer;

//最后我们进入仿真循环:

viewer.setSceneData( root );

return viewer.run();

}

第三课使用内嵌几何形状(Shape)对象,改变渲染状态

目标?

使用osg::Shape实例构建场景。使用osg::StateSet控制几何形状的渲染。

Shape类的使用?

Shape类是各种内嵌几何形状的基类。它可以用于剔除和碰撞检测,或者设计并生成简单几何形体。下面这些类均派生自Shape 类:

?TriangleMesh

?Sphere

?InfinitePlane

?HeightField

?Cylinder

?Cone

?CompositeShape

?Box

如果要渲染这些内嵌形体,我们需要首先将其与Drawable类的实例相关联。我们可以使用ShapeDrawable类来完成这一功能。它派生自Drawable类,并提供了关联Shape实例的方法。正因为ShapeDrawable是继承自Drawable的,它的实例因而可以被添加到Geode实例中。下面的代码演示了在场景中添加单位立方体的方法:

//创建场景的根节点

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

//声明Box类(派生自Shape)的实例。构造函数的参数为:osg::Vec3的中心位置,浮点数定义统一的高/宽/深度。

// (我们也可以分别输入不同的高度、宽度、深度值)

osg::Box* unitCube = new osg::Box( osg::Vec3(0,0,0), 1.0f);

//声明ShapeDrawable类的实例,使用刚才创建的unitCube作为传递参数。这个类派生自Drawable类,因此可以直接添加到Geode 实例中。

osg::ShapeDrawable* unitCubeDrawable = new osg::ShapeDrawable(unitCube);

// 声明Geode类的实例

osg::Geode* basicShapesGeode = new osg::Geode();

// 将单位立方体添加到Geode中

basicShapesGeode->addDrawable(unitCubeDrawable);

// 将Geode添加到场景中

root->addChild(basicShapesGeode);

创建球的方法与此类同。如下面的代码所示:

// 在原点创建单位半径的球

osg::Sphere* unitSphere = new osg::Sphere( osg::Vec3(0,0,0), 1.0);

osg::ShapeDrawable* unitSphereDrawable = new osg::ShapeDrawable(unitSphere);

现在我们可以对球作位置变换后添加到场景中,以便将其与已经置于原点上的立方体区分开。注意unitSphereDrawable是不能直接添加到场景中的(它不是Node的派生类),因此我们需要为其创建一个新的Geode叶节点:

osg::PositionAttitudeTransform* sphereXForm =

new osg::PositionAttitudeTransform();

sphereXForm->setPosition(osg::Vec3(2.5,0,0));

osg::Geode* unitSphereGeode = new osg::Geode();

root->addChild(sphereXForm);

sphereXForm->addChild(unitSphereGeode);

unitSphereGeode->addDrawable(unitSphereDrawable);

设置渲染状态?

前一个教程已经演示了创建纹理,从文件加载纹理图片,并关联纹理到StateSet对象的过程。下面的代码将设置两种不同的渲染状态:一个使用BLEND纹理模式,另一个使用DECAL模式。首先是BLEND模式:

//创建使用BLEND模式的渲染状态对象

osg::StateSet* blendStateSet = new osg::StateSet();

//声明TexEnv实例,设置模式为BLEND

osg::TexEnv* blendTexEnv = new osg::TexEnv;

blendTexEnv->setMode(osg::TexEnv::BLEND);

// 使用纹理0,也就是上一章加载的纹理

blendStateSet->setTextureAttributeAndModes

(0,KLN89FaceTexture,osg::StateAttribute::ON);

// 设置纹理单元0所用的纹理环境

blendStateSet->setTextureAttribute(0,blendTexEnv);

现在我们重复刚才的过程,但是将纹理环境模式设置为DECAL:

osg::StateSet* decalStateSet = new osg::StateSet();

osg::TexEnv* decalTexEnv = new osg::TexEnv();

decalTexEnv->setMode(osg::TexEnv::DECAL);

decalStateSet->setTextureAttributeAndModes

(0,KLN89FaceTexture,osg::StateAttribute::ON);

decalStateSet->setTextureAttribute(0,decalTexEnv);

现在我们将刚才创建的渲染状态对象关联到场景图形的节点。当场景图形执行绘制遍历(根节点->叶节点)时,渲染状态会暂存起来。如果某个节点没有与之关联的渲染状态,那么它将继承其父节点的渲染状态(换句话说,对于有不止一个父节点的节点来说,它可能有多种不同的渲染状态)。

root->setStateSet(blendStateSet);

unitSphereGeode->setStateSet(decalStateSet);

最后我们进入仿真循环:

osgViewer::Viewer viewer;

viewer.setSceneData( root );

return viewer.run();

第四课StateSet的工作流程

场景图形在遍历场景的过程中,会自动判断哪一些几何体要送入图形管道进行渲染。在遍历过程中,场景图形还要收集几何体渲染状态的信息。这些信息就保存在osg::StateSet实例中。StateSet包含了一个OpenGL属性/值的列表,它可以与场景中的节点相关联。在渲染之前的遍历过程中,StateSet会从根节点一直向叶节点进行积累。如果某个节点只是简单地继承上一节点的状态,那么与它关联的StateSet也不会发生改变。

我们可以使用一些附加的特性来提升工作的灵活性。渲染状态所保存的属性可以设置为OVERRIDE,也就是说,该节点的所有子节点,无论其渲染状态是什么,都将继承父节点的渲染属性。但是OVERRIDE也可能存在一种例外,如果某个子节点的渲染属性设置为PROTECTED,那么它将忽略父节点的相应属性,而使用自己设定的属性值。

示例?

下面的例子演示了渲染状态对场景图形的影响。根节点使用BLEND模式。如果它的子节点没有改变任何渲染属性值,则子节点的渲染状态也不会发生改变,如根节点的右子树所示。右子树的节点没有指定渲染状态,因此它的渲染方式与根节点相同。而对于节点5来说,虽然纹理的混合模式没有改变,但是它已经关联了新的纹理。

根节点的左子树设置纹理模式为DECAL,其它的渲染属性与根节点相同。节点3将FOG属性设置为ON并指定为OVERRIDE。对于节点2的左子节点(节点3),其FOG属性设置为OFF,但是由于没有指定PROTECTED方式,且父节点为OVERRIDE方式,因此FOG属性依然为ON。而对于右子节点(节点4),其FOG属性使用PROTECTED方式并设定为OFF,此时它将忽略父节点的相应设置。

代码?

下面的代码用于控制渲染状态的设定并将其关联到节点。

//设置osg::TexEnv实例为BLEND模式,将TexEnv属性和一幅纹理关联到纹理单元0

blendTexEnv->setMode(osg::TexEnv::BLEND);

stateRootBlend->setTextureAttribute(0,blendTexEnv,osg::StateAttribute::ON);

stateRootBlend->setTextureAttributeAndModes(0,ocotilloTexture,osg::StateAttribute::ON);

// 对于节点5,重新设置其渲染单元0的纹理。其它的渲染属性将继承父节点的属性(渲染模式属性仍为BLEND)

stateFiveDustTexture->setTextureAttributeAndModes(0,dustTexture,osg::StateAttribute::ON);

// 设置osg::TexEnv实例为DECAL模式,将其关联到stateOneDecal

decalTexEnv->setMode(osg::TexEnv::DECAL);

stateOneDecal->setTextureAttribute(0,decalTexEnv,osg::StateAttribute::ON);

// 对于stateTwo,设置FOG属性为ON并设置OVERRIDE,所有的子树将自动继承它的渲染状态,除非设置了PROTECTED标志stateTwoFogON_OVRD->setAttribute(fog, osg::StateAttribute::ON);

stateTwoFogON_OVRD->setMode(GL_FOG, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

// stateThree试图关闭FOG属性,但是由于父节点的渲染状态设置为OVERRIDE,因此FOG的设置没有发生变化(仍为ON)stateThreeFogOFF->setMode(GL_FOG, osg::StateAttribute::OFF);

// stateFour设置了PROTECTED标志,因此它可以重载父节点的渲染状态了

stateFourFogOFF_PROT->setMode(GL_FOG, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);

// 将上面的各个渲染状态实例应用到场景图形的节点上

root->setStateSet(stateRootBlend);

mtOne->setStateSet(stateOneDecal);

mtTwo->setStateSet(stateTwoFogON_OVRD);

mtThree->setStateSet(stateThreeFogOFF);

mtSix->setStateSet(stateFiveDustTexture);

mtFour->setStateSet(stateFourFogOFF_PROT);

第五课从文件加载模型并放置在场景中

目标?

读取几何模型并添加到场景中,调整其中一个模型的位置并设置一个仿真循环来浏览场景。

读取几何模型并添加到场景?

OpenSceneGraph使用文件插件来读取各种格式的文件。目前它主要支持这样几种几何模型文件格式:3dc,3ds,flt,geo,iv,ive,lwo,md2,obj,osg等,以及这些图片文件格式:bmp,gif,jpeg,rgb,tga,tif。

OSG的发行版附带了多个开放场景图形格式(.osg)的几何模型。在本例中我们将读取一个.osg文件以及一个MPI Open Flight(.flt)文件。为了方便系统搜索模型,我们可以在OSG_FILE_PATH所指定的路径(例如C:\Projects

\OpenSceneGraph\OpenSceneGraph-Data)下建立一个models文件夹,从以下地址下载模型文件并解压:

https://www.360docs.net/doc/134406717.html,/cs/sullivan/osgTutorials/Download/T72-tank.zip

几何模型需要表示为场景图形的节点。因此,我们应当声明一个指向osg::Node实例的指针来加载和处理模型文件(需要增加一些头文件的支持)。

#include

#include

...

osg::Node* cessnaNode = NULL;

osg::Node* tankNode = NULL;

...

cessnaNode = osgDB::readNodeFile("cessna.osg");

tankNode = osgDB::readNodeFile("Models/T72-tank/t72-tank_des.flt");

上面的语句是加载数据所必需的。现在我们可以将加载的模型作为场景图形的一部分了,将模型作为位置变换节点的子节点载

入,以便控制它在场景中的位置。

// 声明一个作为场景图形根节点的组节点,它可以接受其它节点作为

// 自己的子节点,因此我们需要使用Group节点。

// Node节点类是泛指所有类型的节点。而Group类是节点类型的一种,

// 它可以对子节点进行增减和控制。

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

root->addChild(cessnaNode);

// 声明并初始化位置变换节点

osg::PositionAttitudeTransform* tankXform =

new osg::PositionAttitudeTransform();

//使用osg::Group的addChild方法将位置变换节点作为根节点

//的子节点添加,坦克节点作为位置变换节点的子节点添加。

root->addChild(tankXform);

tankXform->addChild(tankNode);

// 初始化一个Vec3的实例,用于确定坦克在场景中的位置。

osg::Vec3 tankPosit(5,0,0);

tankXform->setPosition( tankPosit );

现在我们的场景图形由一个根节点和两个子节点组成,其中一个是飞机(cessna.osg)的几何模型,另一个则是子树。子树中包含了位置变换节点和它的唯一子节点,坦克的几何模型。为了观察这个场景,我们设置一个视窗类并编写仿真循环。代码如下:

#include

// 声明视窗类

osgViewer::Viewer viewer;

// 将场景图形关联给视窗类

viewer.setSceneData( root );

// 添加视图的用户控制工具,即轨迹球漫游器

viewer.addCameraManipulator(new osgGA::TrackballManipulator);

// 创建程序窗口并启动工作线程

viewer.realize();

// 进入仿真循环。在用户按下ESC键之前,viewer.done()都会返回false。

// 用户也可以使用自己的键盘/鼠标事件处理器来替换缺省的处理器

while( !viewer.done() )

{

//执行新的一帧,其中封装了以下几种Viewer类操作:

// advance()通知程序向前移动一帧

// eventTraversal()收集事件并传递给事件处理器和回调

// updateTraversal()用于调用更新回调

// renderingTraversals()负责同步所有的渲染线程,并分配拣选,绘制和交换缓存

viewer.frame();

}

现在我们可以编译和运行上面的代码了(注意代码的调用格式,还有main函数是否已经添加了)。在运行时按下h键将触发帮助菜单。按下ESC可以退出程序。

第六课osgText,抬头显示(HUD),渲染元(Rend erBin)

目标?

向场景添加文字- 包括抬头显示信息(HUD)样式的文字,以及放置于场景中的文字。

概述:?

Text文字类派生自Drawable类。换句话说,文字类的实例可以被添加到Geode中,并作为几何体渲染。Text类的方法列表请参照API 参考文档。此外,“Example osgtext”中也演示了各种方法的使用。本教程仅仅提供对Text类各种功能的简单介绍。绘制HUD包括两个基本概念:

1.创建一个子树,其顶层节点设置了适当的投影和模型矩阵。

2.将HUD子树的几何体关联到适当的渲染元(RenderBin),以确保HUD几何体在场景图形的其余部分全部渲染完毕后才进

行渲染。

用于渲染HUD的子树包括了一个投影矩阵和一个模型矩阵。我们使用水平和垂直范围等于屏幕尺寸的正交投影矩阵,以保证文字坐标与像素坐标相等。为了保证模型正确,我们还需要使用单位矩阵作为模型观察矩阵。

渲染HUD时,我们需要将文字几何体关联到特定的渲染元(RenderBin)中。后者允许用户指定几何体绘制的顺序。这样我们就可以确保HUD几何体是在场景的最后进行渲染的。

代码?

首先,我们声明所需的变量:osg::Text和osg::Projection对象

osg::Group* root = NULL;

osg::Node* tankNode = NULL;

osg::Node* terrainNode = NULL;

osg::PositionAttitudeTransform* tankXform;

//HUD几何体的叶节点

osg::Geode* HUDGeode = new osg::Geode();

// 用于作HUD显示的Text实例

osgText::Text* textOne = new osgText::Text();

// 这个文字实例将跟随坦克显示

osgText::Text* tankLabel = new osgText::Text();

// 投影节点用于定义HUD的视景体(view frustrum)

osg::Projection* HUDProjectionMatrix = new osg::Projection;

从文件中读取模型,并设置场景图形的结构,参见前一章教程。

// 初始化根节点

root = new osg::Group();

osgDB::FilePathList pathList = osgDB::getDataFilePathList();

pathList.push_back

("C:\\Projects\\OpenSceneGraph\\OpenSceneGraph-Data\\NPSData\\Models\\T72-Tank\\");

pathList.push_back

("C:\\Projects\\OpenSceneGraph\\OpenSceneGraph-Data\\NPSData\\Models\\JoeDirt\\");

pathList.push_back

("C:\\Projects\\OpenSceneGraph\\OpenSceneGraph-Data\\NPSData\\Textures\\");

osgDB::setDataFilePathList(pathList);

// 读入模型并关联到节点

tankNode = osgDB::readNodeFile("t72-tank_des.flt");

terrainNode = osgDB::readNodeFile("JoeDirt.flt");

// 初始化位置变换节点,用于放置坦克模型

tankXform = new osg::PositionAttitudeTransform());

tankXform->setPosition( osg::Vec3d(5,5,8) );

// 构件场景。将地形节点和位置变换节点关联到根节点

root->addChild(terrainNode);

root->addChild(tankXform);

tankXform->addChild(tankNode);

下一步,设置场景显示HUD文字。这里我们向场景中添加一个子树,其顶层节点使用投影和模型观察矩阵。

// 将投影矩阵添加到根节点。投影矩阵的水平和垂直范围与屏幕的尺寸

// 相同。因此该节点子树中的位置坐标将等同于像素坐标

HUDProjectionMatrix->setMatrix(osg::Matrix::ortho2D(0,1024,0,768));

// HUD模型观察矩阵应使用单位矩阵

osg::MatrixTransform* HUDModelViewMatrix = new osg::MatrixTransform;

HUDModelViewMatrix->setMatrix(osg::Matrix::identity());

// 确保模型观察矩阵不会被场景图形的位置变换影响

HUDModelViewMatrix->setReferenceFrame(osg::Transform::ABSOLUTE_RF);

// 添加HUD投影矩阵到根节点,添加HUD模型观察矩阵到HUD投影矩阵。

// 模型观察矩阵节点的所有子节点都可以使用该投影矩阵进行视景

// 浏览,并使用模型观察矩阵来安置位置

root->addChild(HUDProjectionMatrix);

HUDProjectionMatrix->addChild(HUDModelViewMatrix);

现在我们设置几何体。我们创建一个与屏幕坐标对齐的四边形,并设置其颜色和纹理参数。

// 将包含HUD几何体的Geode节点作为HUD模型观察矩阵的子节点

HUDModelViewMatrix->addChild( HUDGeode );

// 设置HUD的四边形背景,并添加到Geode节点

osg::Geometry* HUDBackgroundGeometry = new osg::Geometry();

osg::Vec3Array* HUDBackgroundVertices = new osg::Vec3Array;

HUDBackgroundVertices->push_back( osg::Vec3( 0, 0,-1) );

HUDBackgroundVertices->push_back( osg::Vec3(1024, 0,-1) );

HUDBackgroundVertices->push_back( osg::Vec3(1024,200,-1) );

HUDBackgroundVertices->push_back( osg::Vec3( 0,200,-1) );

osg::DrawElementsUInt* HUDBackgroundIndices =

new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0);

HUDBackgroundIndices->push_back(0);

HUDBackgroundIndices->push_back(1);

HUDBackgroundIndices->push_back(2);

HUDBackgroundIndices->push_back(3);

osg::Vec4Array* HUDcolors = new osg::Vec4Array;

HUDcolors->push_back(osg::Vec4(0.8f,0.8f,0.8f,0.8f));

osg::Vec2Array* texcoords = new osg::Vec2Array(4);

(*texcoords)[0].set(0.0f,0.0f);

(*texcoords)[1].set(1.0f,0.0f);

(*texcoords)[2].set(1.0f,1.0f);

(*texcoords)[3].set(0.0f,1.0f);

HUDBackgroundGeometry->setTexCoordArray(0,texcoords);

osg::Texture2D* HUDTexture = new osg::Texture2D;

HUDTexture->setDataVariance(osg::Object::DYNAMIC);

osg::Image* hudImage;

hudImage = osgDB::readImageFile("HUDBack2.tga");

HUDTexture->setImage(hudImage);

osg::Vec3Array* HUDnormals = new osg::Vec3Array;

HUDnormals->push_back(osg::Vec3(0.0f,0.0f,1.0f));

HUDBackgroundGeometry->setNormalArray(HUDnormals);

HUDBackgroundGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);

HUDBackgroundGeometry->addPrimitiveSet(HUDBackgroundIndices);

HUDBackgroundGeometry->setVertexArray(HUDBackgroundVertices);

HUDBackgroundGeometry->setColorArray(HUDcolors);

HUDBackgroundGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);

HUDGeode->addDrawable(HUDBackgroundGeometry);

我们需要创建一个osg::StateSet,并禁止深度测试(总是在屏幕上绘制),允许Alpha混合(使HUD背景透明),以保证HUD的渲染正确。然后我们使用一个指定数字的渲染元来分配几何体在拣选遍历中的渲染顺序。代码如下所示:

//设置渲染状态,使用上面定义的纹理

osg::StateSet* HUDStateSet = new osg::StateSet();

HUDGeode->setStateSet(HUDStateSet);

HUDStateSet->

setTextureAttributeAndModes(0,HUDTexture,osg::StateAttribute::ON);

//打开GL_BLEND混合模式(以保证Alpha纹理正确)

HUDStateSet->setMode(GL_BLEND,osg::StateAttribute::ON);

// 禁止深度测试,因此几何体将忽略已绘制物体的深度值,直接进行绘制

HUDStateSet->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);

HUDStateSet->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );

// 确认该几何题在最后进行绘制。渲染元(RenderBin)按照数字顺序执行渲染,因此我们设置一个较大的数字值

HUDStateSet->setRenderBinDetails( 11, "RenderBin");

最后我们设置文字。由于osg::Text继承自osg::Drawable,其实例可以作为osg::Geode实例的子节点添加到场景中。

// 添加文字到Geode叶节点中

HUDGeode->addDrawable( textOne );

// 设置HUD文字的参数

textOne->setCharacterSize(25);

textOne->setFont("C:/WINDOWS/Fonts/impact.ttf");

textOne->setText("Not so good");

textOne->setAxisAlignment(osgText::Text::SCREEN);

textOne->setPosition( osg::Vec3(360,165,-1.5) );

textOne->setColor( osg::Vec4(199, 77, 15, 1) );

// 声明一个叶节点来保存坦克的标签文字

osg::Geode* tankLabelGeode = new osg::Geode();

// 将坦克标签添加到场景中

tankLabelGeode->addDrawable(tankLabel);

tankXform->addChild(tankLabelGeode);

// 设置坦克标签文字的参数,与坦克的坐标对齐,

// 这里使用XZ_PLANE保证文字与坦克的XZ平面对齐

tankLabel->setCharacterSize(5);

tankLabel->setFont("/fonts/arial.ttf");

tankLabel->setText("Tank #1");

tankLabel->setAxisAlignment(osgText::Text::XZ_PLANE);

// 设置文字渲染时包括一个对齐点和包围矩形

tankLabel->setDrawMode(osgText::Text::TEXT |

osgText::Text::ALIGNMENT |

osgText::Text::BOUNDINGBOX);

tankLabel->setAlignment(osgText::Text::CENTER_TOP);

tankLabel->setPosition( osg::Vec3(0,0,8) );

tankLabel->setColor( osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) );

最后,设置视景类并进入仿真循环。

osgViewer::Viewer viewer;

viewer.setSceneData( root );

return viewer.run();

第七课搜索并控制开关节点和DOF(自由度)节点

目标?

对于包含开关节点和DOF节点的场景图形,搜索指定的节点并更新其内容。

搜索场景图形中的一个有名节点?

模型文件可能包含了各种不同的节点类型,用户通过对这些节点的使用来更新和表达模型的各个部分。使用osgSim::MultiSwitch多重节点可以在多个模型渲染状态间进行选择。例如,对坦克模型使用多重节点,用户即可自行选择与完整的或者损坏的坦克相关联的几何体以及渲染状态。模型中还可以包含DOF节点,以便清晰表达坦克的某个部分。例如炮塔节点可以旋转,机枪节点可以升高。炮塔旋转时,炮塔体(包括机枪)的航向角(heading)与坦克的航向角相关联,而机枪抬升时,机枪的俯仰角(pitch)与炮塔的俯仰角相关联。

对这些节点进行更新时,我们需要一个指向节点的指针。而我们首先要获取节点的名字,才能得到该节点的指针。而获取节点的名称,主要有这样一些方法:咨询建模人员;使用其它文件浏览器(对于.flt文件,可以使用Creator或者Vega)浏览模型;或者使用OpenSceneGraph。用户可以根据自己的需要自由运用OSG的功能。例如在场景图形中载入flt文件,并且在仿真过程中将整个场景保存成.osg文件。osg文件使用ASCII格式保存,因此用户可以使用各种文本处理软件(写字板,记事本)对其进行编辑。在坦克模型文件中,你可以发现一个名为“sw1”的开关节点,它有两个子节点“good”和“bad”,分别指向坦克未损坏和损坏的状态。坦克模型的.osg文件可以从这里下载:

https://www.360docs.net/doc/134406717.html,/cs/sullivan/osgTutorials/Download/T72Tank.osg

现在我们已经获得了需要控制的开关节点的名称(sw1),亦可获取其指针对象。获取节点指针的方法有两种:一是编写代码遍历整个场景图形;二是使用后面将会介绍的访问器(visitor)。在以前的教程中,我们已经知道如何加载flight文件,将其添加到场景并进入仿真循环的方法。

#include

#include

#include

#include

#include

int main()

{

osg::Node* tankNode = NULL;

osg::Group* root = NULL;

osg::Vec3 tankPosit;

osg::PositionAttitudeTransform* tankXform;

tankNode = osgDB::readNodeFile("Models/T72-tank/t72-tank_des.flt");

root = new osg::Group();

tankXform = new osg::PositionAttitudeTransform();

root->addChild(tankXform);

tankXform->addChild(tankNode);

tankPosit.set(5,0,0);

tankXform->setPosition( tankPosit );

osgViewer::Viewer viewer;

viewer.setSceneData( root );

return viewer.run();

}

现在我们需要修改上述代码,以添加查找节点的函数。下面的递归函数有两个参数值:用于搜索的字符串,以及用于指定搜索开始位置的节点。函数的返回值是指定节点子树中,第一个与输入字符串名称相符的节点实例。如果没有找到这样的节点,函数将返回NULL。特别要注意的是,使用访问器将提供更为灵活的节点访问方式。而下面的代码只用于展示如何手动编写场景图形的遍历代码。

osg::Node* findNamedNode(const std::string& searchName,

osg::Node* currNode)

{

osg::Group* currGroup;

osg::Node* foundNode;

// 检查输入的节点是否是合法的,

// 如果输入节点为NULL,则直接返回NULL。

if ( !currNode)

{

return NULL;

}

// 如果输入节点合法,那么先检查该节点是否就是我们想要的结果。

// 如果确为所求,那么直接返回输入节点。

if (currNode->getName() == searchName)

{

return currNode;

}

// 如果输入节点并非所求,那么检查它的子节点(不包括叶节点)情况。

// 如果子节点存在,则使用递归调用来检查每个子节点。

// 如果某一次递归的返回值非空,说明已经找到所求的节点,返回其指针。

// 如果所有的节点都已经遍历过,那么说明不存在所求节点,返回NULL。

currGroup = currNode->asGroup(); // returns NULL if not a group.

if ( currGroup )

{

for (unsigned int i = 0 ; i < currGroup->getNumChildren(); i ++)

{

foundNode = findNamedNode(searchName, currGroup->getChild(i));

if (foundNode)

return foundNode; // 找到所求节点。

}

return NULL; // 遍历结束,不存在所求节点。

}

else

{

return NULL; // 该节点不是组节点,返回NULL

}

}

现在我们可以在代码中添加这个函数,用于查找场景中指定名称的节点并获取其指针。注意这是一种深度优先的算法,它返回第一个符合的节点指针。我们将在设置场景之后,进入仿真循环之前调用该函数。函数返回的开关节点指针可以用于更新开关的状态。下面的代码用于模型载入后,执行查找节点的工作。

osg::Switch* tankStateSwitch = NULL;

osg::Node* foundNode = NULL;

foundNode = findNamedNode("sw1",root);

tankStateSwitch = (osg::Switch*) foundNode;

if ( !tankStateSwitch)

{

std::cout << "tank state switch node not found, quitting." << std::endl;

return -1;

}

按照“访问器”模式搜索有名节点?

“访问器”的设计允许用户将某个特定节点的指定函数,应用到当前场景遍历的所有此类节点中。遍历的类型包括NODE_VISITOR,UPDATE_VISITOR,COLLECT_OCCLUDER_VISITOR和CULL_VISITOR。由于我们还没有讨论场景更新(updating),封闭节点(occluder node)和拣选(culling)的有关内容,因此这里首先介绍NODE_VISITOR(节点访问器)遍历类型。“访问器”同样允许用户指定遍历的模式,可选项包括TRAVERSE_NONE,TRAVERSE_PARENTS,TRAVERSE_ALL_CHILDREN和TRAVERSE_ACTIVE_CHILDREN。这里我们将选择TRAVERSE_ALL_CHILDREN(遍历所有子节点)的模式。

然后,我们需要定义应用到每个节点的函数。这里我们将会针对用户自定义的节点名称进行字符串比较。如果某个节点的名称与指定字符串相符,该节点将被添加到一个节点列表中。遍历过程结束后,列表中将包含所有符合指定的搜索字符串的节点。

为了能够充分利用“访问器”,我们可以从基类osg::NodeVisitor派生一个特定的节点访问器(命名为findNodeVisitor)。这个类需要两个新的数据成员:一个std::string变量,用于和我们搜索的有名节点进行字符串比较;以及一个节点列表变量(std::vector),用于保存符合搜索字符串的所有节点。为了实现上述的操作,我们需要重载“apply”方法。基类的“apply”方法已经针对所有类型的节点(所有派生自osg::Node的节点)作了定义。用户可以重载apply方法来操作特定类型的节点。如果我们希望针对所有的节点进行同样的操作,那么可以重载针对osg::Node类型的apply方法。findNodeVisitor的头文件内容在下表中列出,相关的源代码可以在这里下载:

https://www.360docs.net/doc/134406717.html,/cs/sullivan/osgTutorials/Download/findNodeVisitor.zip

#ifndef FIND_NODE_VISITOR_H

#define FIND_NODE_VISITOR_H

#include

#include

class findNodeVisitor : public osg::NodeVisitor

{

public:

// Default constructor - initialize searchForName to "" and

// set the traversal mode to TRAVERSE_ALL_CHILDREN

findNodeVisitor();

// Constructor that accepts string argument

// Initializes searchForName to user string

// set the traversal mode to TRAVERSE_ALL_CHILDREN

findNodeVisitor(const std::string &searchName);

// The 'apply' method for 'node' type instances.

// Compare the 'searchForName' data member against the node's name.

// If the strings match, add this node to our list

virtual void apply(osg::Node &searchNode);

// Set the searchForName to user-defined string

void setNameToFind(const std::string &searchName);

// Return a pointer to the first node in the list

// with a matching name

osg::Node* getFirst();

// typedef a vector of node pointers for convenience

typedef std::vector nodeListType;

// return a reference to the list of nodes we found

nodeListType& getNodeList() { return foundNodeList; }

private:

// the name we are looking for

std::string searchForName;

// List of nodes with names that match the searchForName string

nodeListType foundNodeList;

};

#endif

现在,我们创建的类可以做到:启动一次节点访问遍历,访问指定场景子树的每个子节点,将节点的名称与用户指定的字符串作比较,并建立一个列表用于保存名字与搜索字符串相同的节点。那么如何启动这个过程呢?我们可以使用osg::Node的“accept”方法来实现节点访问器的启动。选择某个执行accept方法的节点,我们就可以控制遍历开始的位置。(遍历的方向是通过选择遍历模式来决定的,而节点类型的区分则是通过重载相应的apply方法来实现)“accpet”方法将响应某一类的遍历请求,并执行用户指定节点的所有子类节点的apply方法。在这里我们将重载一般节点的apply方法,并选择TRAVERSE_ALL_CHILDREN的遍历模式,因此,触发accept方法的场景子树中所有的节点,均会执行这一apply方法。

在这个例子中,我们将读入三种不同状态的坦克。第一个模型没有任何变化,第二个模型将使用多重开关(multSwitch)来关联损坏状态,而第三个模型中,坦克的炮塔将旋转不同的角度,同时枪管也会升高。

下面的代码实现了从文件中读入三个坦克模型并将其添加到场景的过程。其中两个坦克将作为变换节点(PositionAttitudeTransform)的子节点载入,以便将其位置设置到坐标原点之外。

// 定义场景树的根节点,以及三个独立的坦克模型节点

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

osg::Group* tankOneGroup = NULL;

osg::Group* tankTwoGroup = NULL;

osg::Group* tankThreeGroup = NULL;

// 从文件中读入坦克模型

tankOneGroup = dynamic_cast

(osgDB::readNodeFile("\\Models\\t72-tank\\t72-tank_des.flt"));

tankTwoGroup = dynamic_cast

(osgDB::readNodeFile("\\Models\\t72-tank\\t72-tank_des.flt"));

HumanCAD入门教程翻译 人体建模

HumanCAD? V1.2 入门教程 NexGen人机工程研究公司 6600 Trans 加拿大高速公路 750号公寓 蓬特克莱尔(蒙特利尔),魁北克H9R 4S2 加拿大 电话:5146858593 传真:5146858687 电子邮箱:techsupport@https://www.360docs.net/doc/134406717.html, 网址:https://www.360docs.net/doc/134406717.html, 最后修订:2008-10-30 未经NexGen人机工程研究公司许可,不得以任何形式任何手段(电子、机械、或其他方式),包括复印和录音与该资料或录音系统有关的文件。 NexGen人机工程研究公司2008保留所有权

导言 本教程提供给您一种快捷简单的资源来向您介绍HumanCAD?的各种功能。通过简化一步一步的指示、解释和说明,你将塑造属于你自己的三维人物,揭露你自己的各种人性化功能和CAD工具。HumanCAD ?可以提供给任何设计师,工程师或人为因素的专业。 第一步,通过本教程熟悉HumanCAD ?的主要功能,按键和屏幕的命令。第二个是介绍了一些应用程序和软件的功能。 本教程的第三步也就是最后一步,是以各种姿势、划线和导入不同的三维物体来创建自己的个性化三维人物,应用和编辑有外部负载的模特儿的身体和执行了一系列的生物力学分析,包括预测和NIOSH (美国职业安全及健康研究所)的计算和模拟。 首先,比如一个常见的被称为“举箱子”的动作(看下图),可以看出本教程是非常的简单。这个例子用一中简单的方法来理解了一些应用HumanCAD ?及其各职能。

目录 HumanCAD?的基本操作原理 (4) 主屏幕的所有相关信息 (5) 菜单选项 (6) HumanCAD?速成教程 (11) 1.1.达到量和视觉锥 (13) 1.2.分析模特儿的视野...................................................................... (14) 1.3.样本人机工程学问题 (16) 1.4. 让我们创建一个模特儿 (18) 1.5.让我们构造和操纵模特儿......................................................... . (19) 1.6. 现在让我们来绘制三维对象 (21) 1.7.将力作用在模特儿身上 (22) 1.8.分析模特儿身上的作用力 (23) 1.9.应该成载多大的重量 (24) 关于NexGen人机工程研究公司 (25)

现场管理知识培训教材

教材编号: 编写: 审核: 批准: 版本:V1.0 现场管理培训教材 内容:本教材介绍了现场管理的概念、内容、要点、要求、注意事项和考核办法。 范围:本教材适用于员工培训、现场管理考核。

现场管理知识培训教材 现场管理目标: 规范、高效、团结、整洁

目录 一、现场管理的概念 (2) 二、现场管理理念 (3) 三、现场管理的意义 (4) 四、现场管理要素 (5) 五、现场管理的要求、要点及目的 (7) (一)整理 (7) (二)整顿 (9) (三)清扫................................. 1.1 ..... (四)清洁 (13) (五)素养 (15) 六、现场管理的具体要求 (18) (一)行为规范 (18) (二)物料放置 (25) (三)安全、卫生 (30) 七、现场管理考核要点 (32) (一)行为规范 (32)

现场管理知识培训教材 (二)物料放置 (34) (三)安全、卫生 (35) 八、现场管理的考核办法 (37) (一)考核办法 (37) (二)考核奖惩规定 (38) 1

现场管理知识培训教材 一、现场管理的概念 现场管理就是对生产现场环境全局进行综合考虑,并制订切实可行的计划与措施付诸实施。 它是针对部门中每位员工的日常工作、行为提出的要求,它要求我们保持安全、舒适、明亮的工作环境、和谐融洽的工作气氛,并努力提升自身真、善、美的品质,从而塑造良好的企业形象,实现我们共同的理想。 我们倡导从小事做起,力求使每位员工都养成事事“ 讲究”的习惯,从现在开始,循序渐进、持之以恒,最终达到改善整体工作质量、提高整体工作效率的目的,为公司的稳步发展打下基础。 2

最长的一帧

最长的一帧 王锐(array) 这是一篇有关OpenSceneGraph源代码的拙劣教程,没有任何能赏心悦目的小例子,也不会贡献出什么企业级的绝密的商业代码,标题也只是个噱头(坏了,没人看了^_^)。 本文写作的目的说来很简单,无非就是想要深入地了解一下,OSG在一帧时间,也就是仿真循环的一个画面当中都做了什么。 对OSG有所了解之后,我们也许可以很快地回答这个问题,正如下面的代码所示:while (!viewer.done()) viewer.frame(); 就这样,用一个循环结构来反复地执行frame()函数,直到done()函数的返回值为true 为止。每一次执行frame()函数就相当于完成了OSG场景渲染的一帧,配置较好的计算机可以达到每秒钟一二百帧的速率,而通常仿真程序顺利运行的最低帧速在15~25帧/秒即可。 很好,看来笔者的机器运行frame()函数通常只需要8~10ms左右,比一眨眼的工夫都要短。那么本文就到此结束吗? 答案当然是否定的,恰恰相反,这篇繁琐且可能错误百出的文字,其目的正是要深入frame()函数,再深入函数中调用的函数……一直挖掘下去,直到我们期待的瑰宝出现;当然也可能是一无所获,只是乐在其中。 这样的探索要到什么时候结束呢?从这短短的10毫秒中引申出来的,无比冗长的一帧,又是多么丰富抑或无聊的内容呢?现在笔者也不知道,也许直到最后也不会明了,不过相信深入源代码的过程就是一种享受,希望读者您也可以同我一起享受这份辛苦与快乐。 源代码版本:OpenSceneGraph 2.6.0;操作系统环境假设为Win32平台。为了保证教程的篇幅不致被过多程序代码所占据,文中会适当地改写和缩编所列出的代码,仅保证其执行效果不变,因此可能与实际源文件的内容有所区别。 由于作者水平和精力所限,本文暂时仅对单视景器(即使用osgViewer::Viewer类)的情形作出介绍。 转载请注明作者和https://www.360docs.net/doc/134406717.html, 本文在写作过程中将会用到一些专有名词,它们可能与读者阅读的其它文章中所述有所差异,现列举如下: 场景图形-SceneGraph;场景子树-Subgraph;节点-Node;摄像机-Camera;渲染器-Renderer;窗口-Window;视口-Viewport;场景-Scene;视图-View;视景器-Viewer;漫游器-Manipulator;访问器-Visitor;回调-Callback;事件-Event;更新-Update;筛选-Cull;绘制-Draw。 第一日 好了,在开始第一天的行程之前,请先打开您最惯用的编程工具吧:VisualStudio?CodeBlocks?UltraEdit?SourceInsight?Emacs?Vim?或者只是附件里那个制作低劣的记事本……总之请打开它们,打开OpenSceneGraph-2.6.0的源代码文件夹,打开

美军舰艇舷号舰名表

美军主要作战舰艇舷号舰名一览表一、航空母航中文名/英文名、舷号 小鹰级 小鹰Kity Hawk CV63 星座Constellation CV64 美国America CV66 约翰·菲茨杰拉德·肯尼迪John F Kennedy CV67 福莱斯特级 福莱斯特Forestal AVT59 萨拉托加Salatoga CV60 突击者Ranger CV61 独立Independence CV62 企业级 企业Enterprise CVN65 尼米兹级 切斯特·尼米兹Chester Nimitz CVN68 德怀特·艾森豪威尔Dwight D Eisenhower CVN69 卡尔·文森Carl Vinson CVN70 西奥多·罗斯福Theodore Roosevelt CVN71 亚伯拉罕·林肯Abraham Lincoln CVN72 乔治·华盛顿George Washington CVN73 约翰·斯坦尼斯John C Stennis CVN74 哈里·杜鲁门Harry Truman CVN75 罗纳德·里根Ronald Reagan CVN76 乔治·布什George Bush CVN77 二、巡洋舰中文名/英文名、舷号 提康德罗加级 提康德罗加Ticonderoga CG47 约克城Yorktown CG48 文森斯Vincennes CG49 福奇山谷Valley Forge CG50 托马斯·盖茨Thomass S Gates CG51 邦克山Bunker Hill CG52 莫比尔湾Mobile Bay CG53

安提坦Antietam CG54 莱特湾Leyte Gulf CG55 圣贾辛托San Jacinto CG56 张伯伦湖Lake Champlain CG57 菲律宾海Philippine Sea CG58 普林斯顿Princeton CG59 诺曼底Normandy CG60 蒙特里Monterey CG61 钱瑟罗斯维尔Chancellorsville CG62 考彭斯Coepens CG63 葛底斯堡Gettysburg CG64 乔辛Chosin CG65 休城Hue City CG66 希洛Shiloh CG67 安齐奥Anzio CG68 维克斯堡Vicksburg CG69 伊利湖Lake Erie CG70 圣乔治角Cape ST George CG71 维拉湾Vella Gulf CG72 皇家港Port Royal CG73 三、驱逐舰中文名/英文名、舷号 阿利伯克级 阿利?伯克Arleigh Burk DDG51 约翰?巴里John Barry DDG52 约翰?保罗?琼斯John Paul Jones DDG53 柯蒂斯?威勃Curts Wilbur DDG54 斯托特Stout DDG55 约翰?麦凯恩John S Mccain DDG56 米切尔Mitscher DDG57 拉布恩Laboon DDG58 拉塞尔Russell DDG59 保罗?汉密尔顿Paul Hamilton DDG60 拉梅奇Ramage DDG61 菲茨杰拉德Fitzgerald DDG62 斯特德姆Stethem DDG63 卡尼Carney DDG64 本福尔德Benfold DDG65

德意志帝国海军舰船名单

大型水面战斗舰艇 俾斯麦级大型战列舰2艘;(全部战沉) 沙恩霍斯特级战列舰2艘;(一艘战沉,一艘重创后报废并作为封锁船沉没) 德意志级袖珍战舰3艘;(一艘39年被迫自沉,两艘45年在空袭中被击毁) 希佩尔海军上将级重巡洋舰5艘,完成3艘,LUTZOW卖给苏联参加了二战(半完成状态),赛德利兹改装航母完成百分之95后战争结束。服役3艘中,一艘40年战沉在挪威,一艘45年在空袭中被击毁,欧根亲王号于战后的美国原子弹试验中被摧毁。 埃姆登级轻巡洋舰1艘,45年空袭中被摧毁。 K级轻巡洋舰3艘,2艘战沉于40年的挪威,1艘战争末期被重创后自沉。 纽伦堡级轻巡洋舰1艘,战后赔偿给苏联。 莱比锡级轻巡洋舰1艘,战后于46年作为军火销毁船故意沉没。 NIOBE号轻巡洋舰,一战德国海军的老船,在二战德国海军里服役很短。原是南斯拉夫海军训练舰,被意大利俘获后成为轻巡洋舰,43年被德军俘获,由德国、克罗地亚海军人员共同驾驶。43年底搁浅,次日被英国鱼雷快艇击毁。 齐柏林级2艘,首舰齐柏林号,完工百分之85,安装有火炮。45年自沉,战后苏联打捞到列宁格勒作为靶舰击沉。另外一艘没有名字,完成百分之60后在船台解体。 赛德利兹号,原同名重巡洋舰,完成百分之95。 中型战斗舰艇 Z级22艘; 改良Z级18艘; 俘获自荷兰的ZH1; 俘获自希腊的ZG3; 战后这些驱逐舰有15艘幸存,被赔偿给了苏联、英国和美国 鱼雷艇(雷击舰) 1923级6艘;

1924级6艘; 1935级9艘; 1937级12艘; 1939级舰队鱼雷艇15艘; T107级4艘(一战后残余的德国鱼雷艇,排水量700T) T152级5艘(同上) T196号(同上,排水量500T) 缴获自挪威的4艘700T、2艘200T、12艘100T鱼雷艇; 缴获自荷兰的TFA9号鱼雷回收艇; 缴获自丹麦的6艘200-300T鱼雷艇; 缴获自法国的3艘900T鱼雷艇; 缴获自意大利海军的33艘鱼雷艇(包括8艘前驱逐舰); 1939级扫雷舰69艘; 1940级扫雷舰131艘; 1941级扫雷舰17艘; 1916级扫雷舰约30艘; 缴获自波兰的扫雷舰2艘; 缴获自丹麦的扫雷舰2艘; 其它杂牌扫雷舰若乾艘; 还缴获了一些自沉的扫雷舰,没有服役 路易斯皇后号,2000T,原德国小型客轮,39年改装成布雷舰,装备水雷200枚; 坦能堡号,4000T,前德国客轮,39年改装成布雷舰,40年和另外两艘德国布雷舰(一艘是汉斯施塔特·但泽号,还有一艘好像是PRESSUE)集体触雷沉没;

OSG(美国海军NPS)教程学习加实践(2)

在编程开始前要认识一下*.tga后缀的文件: TGA格式(Tagged Graphics)是由美国Truevision公司为其显示卡开发的一种图像文件格式,文件后缀为“.tga”,已被国际上的图形、图像工业所接受。 TGA的结构比较简单,属于一种图形、图像数据的通用格式,在多媒体领域有很大影响,是计 算机生成图像向电视转换的一种首选格式。 TGA图像格式最大的特点是可以做出不规则形状的图形、图像文件,一般图形、图像文件都为四方形,若需要有圆形、菱形甚至是缕空的图像文件时,TGA可就派上用场了! TGA格式支持压缩,使用不失真的压缩算法。 在工业设计领域,使用三维软件制作出来的图像可以利用TGA格式的优势,在图像内部生成一个Alpha(通道),这个功能方便了在平面软件中的工作。 ========================================================================== ======== #include #include #include #include #include #include #include #include #include using namespace std; osg::Geode* createPyramid() { osg::Geode* pyramidGeode = new osg::Geode(); osg::Geometry* pyramidGeometry = new osg::Geometry(); pyramidGeode->addDrawable(pyramidGeometry); // 指定顶点 osg::Vec3Array* pyramidVertices = new osg::Vec3Array; pyramidVertices->push_back( osg::Vec3(0, 0, 0) ); // 左前 pyramidVertices->push_back( osg::Vec3(2, 0, 0) ); // 右前 pyramidVertices->push_back( osg::Vec3(2, 2, 0) ); // 右后 pyramidVertices->push_back( osg::Vec3( 0,2, 0) ); // 左后 pyramidVertices->push_back( osg::Vec3( 1, 1,2) ); // 塔尖 // 将顶点数组关联给几何体 pyramidGeometry->setVertexArray( pyramidVertices ); // 根据底面的四个顶点创建底面四边形(QUAD) osg::DrawElementsUInt* pyramidBase =

二战世界各国海军所有舰艇名单

二战世界各国海军所有舰艇编号及名称 德意志第三帝国 一、航空母舰: 1)“格拉夫·齐柏林”号航空母舰· 二、战列舰: 1)俾斯麦级战列舰:俾斯麦号、提尔皮茨号· 2)德意志级袖珍战列舰:“德意志”号、“舍尔海军上将”号、“格拉夫·斯佩海军上将”号·3)沙恩霍斯特级战列巡洋舰:“沙恩霍斯特”号、“格奈森诺”号· 三、巡洋舰: 1)希佩尔海军上将级重巡洋舰:“希佩尔海军上将”号、“布吕歇尔”号、“欧根亲王”号2)柯尼斯堡级轻型巡洋舰:柯尼斯堡号、卡尔斯鲁厄号、科隆号 3)轻型巡洋舰:“埃姆登”号、“莱比锡”号、“纽伦堡”号 4)辅助巡洋舰:“亚特兰蒂斯”号、“奥利安”号、“科罗内尔”号、“汉萨”号 四、驱逐舰: Z级驱逐舰 1)1934年级驱逐舰· Z-1莱伯勒希特·麻司、Z-2乔治·蒂勒、Z-3马克斯·舒尔茨、Z-4里夏德·拜茨恩、Z-5保罗·雅各比、 Z-6 西奥多·里德尔、Z-7 赫尔曼·舍曼、Z-8 布鲁诺·海纳曼、Z-9 沃尔夫冈·岑克尔、Z-10 汉斯·洛迪、 Z-11 伯恩德·冯·阿尼姆、Z-12 埃里希·吉泽、Z-13 埃里希·克勒纳、 Z-14 弗里德里希·伊恩、Z-15 埃里希·斯坦布林克、Z-16 弗里德里希·埃科尔特。 2)1936年级驱逐舰 Z-17 迪特尔·冯·勒德尔、Z-18 汉斯·吕德曼、Z-19 赫尔曼·库纳、Z-20 卡尔·加尔斯特、Z-21 威廉·海德坎姆、Z-22 安东·施米特。 1936A型驱逐舰Z-23——Z-30 : Z-24、Z-28 1936A改型驱逐舰(增产型)Z-31——Z-39 : Z-31 1936B型驱逐舰Z-35——Z-43,Z-44、Z-45停止建造。 五、潜艇: ⅠA型潜艇U-25、U-26 ⅡA型潜艇U-1——U-6 ⅡB型潜艇U-7——U24、U-120、U-121 ⅡC型潜艇U-56——U-63 ⅠⅩ(ⅠⅩA)型潜艇U-37——U-44 ⅤⅡD型潜艇U-213——U-218 ⅤⅡF型潜艇U-1059——U-1062

美国海军发布无人水面艇主计划

美国海军发布无人水面艇主计划(上) 2007年7月23日,美国海军发布了《海军无人水面艇主计划》。该计划从满足美国海军战略计划、舰队发展以及国防部到2020年部队转型的需求等方面,详细介绍了美国海军未来无人水面艇(USV)的发展计划。全文共分5个部分,即无人水面艇发展设想,无人水面艇的作战使命,发展系列无人水面艇,无人水面艇的技术与工程问题,建议与结论。现将主要内容摘编如下: 一、USV的发展设想 USV的发展设想是:开发和装备成本节约型的USV,改善海军和联合作战能力,支持本土防御、全球反恐作战、非对称作战和常规战争。为提升USV稳定性和耐波能力,协助打击地区性、跨国界、以及全球范围内的敌人,USV将增大目前和未来的平台。USV将完全实现自动化,从而降低通信/数据交换的需求以及操控人员的负担。此外,USV可通过布放和回收仪器设备,收集、发送和处理各类信息,使美军及其盟军能够以最低的风险或代价攻击目标。 为了实现USV的发展设想,USV主计划确定了以下目标: (1)确定USV近期(5年)、中期(5年至10年)和未来(10年以上)的能力,具体包括:任务描述和优先性,每项任务的高层次作战概念(CONOPS),并通过对备选能力进行评估,确定这些能力是否适用于USV。 (2)建立USV的性能级别,使各级USV能够满足能力的需求:①推荐若干级别的水面艇,构建高效的、集团化的、互为补充的能力;②在海军项目中,界定USV类型和尺寸的具体范围;③审查各USV级别内部以及彼此之间的模块化和通用化水平。 (3)评估技术要求以及目前的技术准备情况,为USV平台和相关负载的研制提出相应的技术投资策略。 二、USV的作战使命 根据国防部和海军的指导性文件,这份主计划确定了USV优先发展的7个任务领域,按照优先级排列,包括:反水雷战(MCM);反潜作战(ASW);海上安全(MS);水面作战(SUW);支持特种部队作战(SOF);电子战(EW);支持海上拦截作战(MIO)。针对每一项任务领域,研究团队将开发一种USV 任务包,这个任务包包括平台尺寸/类型、负载和可能的应用描述等。 三、发展系列USV 在2006年举行的USV主计划专题学术讨论会中,一项重要的结论是,界定USV的类型和尺寸级别将有助于协调舰队和USV采办项目,特别是在舰队兼容性、促进民品开发、集中控制、标准化、通用化、模块化和人员系统集成等方面。对于USV来说,最为重要的技术条件是USV能够被海军现役舰艇搭载,或仅需进行较小的改装,因此,通用的海军船型和尺寸成为首先考虑的因素。USV主计划推荐了一个非标准级的USV和三个标准级的USV,这4种级别的USV能够完全满足美国海军USV优先发展的7个任务领域的能力需求,具体包括: “X-级”是一个长3米或更小的非标准级USV,采用非标准模块建造,能够支持特种部队作战、以及海上拦截作战任务。它将提供低层次的情报、侦察、监视能力,以及有限的续航力、有效载荷和适航性,支持有人操作。

Contextcapture建模流程修订版V3.0

Contextcapture建模流程 初学篇 1 新建工程 新建工程,设置工程路径 2 导入照片 导入本机照片。如需集群处理,则需要导入网络路径下的照片,详见6.2工程设置:

导入照片 Set downsampling(设置采样率):该参数只会在空三的过程中对照片进行重采样空三,建模时仍旧使用原始分辨率影像。 Check image files...(检查航片完整性):建模失败的时候可以用此功能进行数据完整性检查。 Import positions...(导入POS):导入POS格式如下, a.如果有多个照片组(Photogroup)则必须保证每个照片组中的照片名称唯一,否则会导入失败; b.POS路径必须为英文;

相机参数 每个照片组(Photogroup)都会有一个相机参数,可以在右键菜单中导入或导出相机检校参数(特别对CC4.4以后版本有用)。 3 空中三角测量 3.1常规空三流程 空三参数设置,如第一次使用,则建议直接按照默认参数,只需“下一步”即可,如欲了解其中参数意义则进入如下内容: (1)设置名称,最好根据飞行架次或项目信息进行设置

(2)参与空三的照片,默认使用全部照片。 (3)照片定位或地理参考设置

(4)空三参数设置,通常默认参数即可 a.对于地名拍摄照片,可能会修改“Keypoints density”、“Pair selection mode”、“Component construction mode”三个选项; b.对于航空拍摄照片,通常使用默认参数,如果多个架次且存在航高不一致的情况,则可能会修改“Pair selection mode”、“Component construction mode”两个 选项;(实例:百里峡漂流两个架次航高不一致)

美国现服役的11艘航母详解

美国现服役的11艘航母 1,企业号(CVN-65)核动力航空母舰。 企业号航母是世界上第一艘核动力航空母舰,它的问世,使航空母舰的发展进入了新纪元。企业号是在1958年2月4日开工,1960年时下水,1961年11月25日正式完工服役。 该舰排水量85,600吨,全长342米,舷宽40米,最大甲板宽76米。武器装备为3座雷声(Raytheon)Mk298联装发射装置导弹、“北约海麻雀"(NATOSeaSparrow)对空导弹、3座(GE/GD)Mk156管20毫米“火神密集阵”(VulcanPhalanx)炮,。一般配备20架F-14“雄猫”(Tomcat)36架F/A-18“大黄蜂”(Hornet),4架EA-6B“徘徊者”(Prowler),4架E-2C“鹰眼”(Hawkeye),8架S-3A/B“北欧海盗”(Viking),4架SH-60F和2架HH-60“海鹰”(Seahawk). 服役35年来,“企业”号为美国海军立下了“汗马功劳”,多次被派往敏感地区和冲突地区,应付突发事件。1962年8月古巴导弹危机时,“企业”号曾参与美国海军封锁古巴的行动。1964年,‘企业’号进行了史无前例的环球航行,途中无需加油和再补给,历时64天,总航程3多海里,充分显示了核动力的巨大续航力。越战期间,,“企业”号曾参与越战的空袭行动,并参与1975年的西贡撤退。1969年1月14日是“企业”号的灾难日,它的飞行甲板突然发生火灾意外并引爆9枚五百磅炸弹,飞行甲板被炸出三个大洞,内部也受创不轻,幸好在数小时抢救后扑灭火势并自力返航,之后的修复作业耗时三个月。2001年9月11日美国本土遭到恐怖份子猛烈攻击时,“企业”号正准备结束在中东的巡航返国,不过立刻被留在当地,并参与了日后阿富汗战争的“持久自由“(Operation Enduring Freedom)作战行动。这艘颠簸半生的“企业”号预定在2013年除役,被新世代核动力航空母舰CVNX的第一艘取代,届时“企业”号已在海上奔驰了52年。 2,尼米兹号(CVN 68) 航空母舰。 尼米兹号航母是一系列尼米兹级核动力航空母舰的首舰。该舰于1972年5月13日正式下水,

二战中的美国海军舰炮[二战舰炮系列1

?相册 ?广场 ?游戏 ?登录 ? ?注册 关注此空间 帝国海军司令部 帝国兴废,在此一战,各员一层,奋勉努力 2010-06-03 17:48 二战中的美国海军舰炮[二战舰炮系列] 战列舰主炮 vj I EQNH^ ?*t~ / |d# 在二战中,随着航空母舰的崛起,战列舰在海上作战的龙头

地位被推翻了。但是战列舰在水面舰艇作战中还是起到了举足轻重的作用,他的主炮就是他的灵魂;同时他是支援两栖登陆作战的利器。 ' ){nX >b 二战中美军共有10级26艘战列舰和战列巡洋舰在役,他们装备了406mm,356mm,和305mm三种口径的主炮。 @ EEOk " l !m< !}r~ Mark 7型406mm/50,装备于依阿华级战列舰。 BU$C4** 这可能是所有在海军服役的最好的战列舰主炮。最初设计为发射较轻的1016公斤的Mark 5型穿甲弹,但在依阿华号开始建造前,他的装弹系统被重新设计以发射1225公斤的Mark 5型“特重”穿甲弹。这种穿甲弹的穿甲能力接近于日本大和级战列舰装备的460mm主炮,但是它的重量不到460mm炮弹的3/4。 b^ %AL v" Mark 7型406mm炮所发射的穿甲弹能穿透9m的水泥,而它的高爆弹能制造一个15m宽6m深的弹坑。 ':xU}{ dlv Mark 7型406mm炮由膛管,身管,外管,和3层套管组成,采用了2道套管环,膛管身管环,炮尾环,和闩锁膛组成。部分组件采用了液压自紧技术制成,炮管镀铬以延长炮管寿命。使用了下启式Welin式断隔螺式炮闩。 7I[(/PibSM 炮管组件示意图

建造中的衣阿华号(BB-61)前炮塔

现场管理目标

现场管理目标 教材编号:001 编写: 审核: 批准: 版本: V1.0 现场管理培训教材 内容及范围 内容:本教材介绍了现场管理的概念、内容、要点、要求、 注意事项和考核办法。 范围:本教材适用于员工培训、现场管理考核。 现场管理知识培训教材 现场管理目标: 规范、高效、团结、整洁 目录 一、现场管理的概念 (2) 二、现场管理理念 (3) 三、现场管理的意义 (4) 四、现场管理要素 (5) 五、现场管理的要求、要点及目的 (7) (一)整理 (7) (二)整顿 (9) (三)清扫 (11) (四)清洁 (13) (五)素养 (15) 六、现场管理的具体要求 (18) (一)行为规范 (18) (二)物料放置 (25) (三)安全、卫生 (30) 七、现场管理考核要点 (32) (一)行为规范 (32) 现场管理知识培训教材 1 (二)物料放置 (34) (三)安全、卫生 (35) 八、现场管理的考核办法 (37) (一)考核办法 (37) (二)考核奖惩规定 (38) 现场管理知识培训教材 2 一、现场管理的概念 现场管理就是对生产现场环境全局进行综合考虑,并制

订切实可行的计划与措施付诸实施。 它是针对部门中每位员工的日常工作、行为提出的要求, 它要求我们保持安全、舒适、明亮的工作环境、和谐融洽的工作气氛,并努力提升自身真、善、美的品质,从而塑造良好的企业形象,实现我们共同的理想。 我们倡导从小事做起,力求使每位员工都养成事事“讲 究”的习惯,从现在开始,循序渐进、持之以恒,最终达到改善整体工作质量、提高整体工作效率的目的,为公司的稳步发展打下基础。 现场管理知识培训教材 3 二、现场管理理念 现场就是市场 被顾客称赞为干净整洁的工厂,对我们的工厂有信心, 乐于下订单,这是我们每一位员工的期望和骄傲。 为了更好地发展,公司必须遵循市场竞争的准则,提升 自身的竞争力。员工也应努力提高自己的素质和技能,因为我们都是这个值得骄傲的团队的一分子,我们就是公司竞争力的源泉。 现场就是服务 我们有着很高的工作效率,我们制造出高质量的产品,我 们协同客户分析、解决问题,因为我们面对的是客户。现场就是服务。 公司在竞争中求发展,现场则是一个窗口,一个服务的窗 口,一个向客户展示我们竞争力的窗口。它向客户展示的是我们企业内在的实力与活力。 现场管理知识培训教材 4 三、现场管理的意义 现场造就品质 卓越的现场管理是确保品质的先决条件。优质的产品来自 于先进高效的管理,来自于优良的工作环境。 现场提高效率 只有规范的现场管理才能保证物流畅通,物流畅通是提 高效率的必要途径,现场管理的目的之一就是要提高生产物流过程的效率。 现场营造团队精神 现场管理能够创造一个清爽的工作环境。这个环境将让 我们心情愉快。喜悦的心情并不是公司带给我们的,而是我们自己创造出来的,我们应为此倍感到自豪。 现场就是我们这个值得骄傲的团队,它要求我们在工作 和其他集体活动中,一定要做到个人服从集体,局部服从整体。现场管理知识培训教材 5

FlightGear2016.4.1+VS2015编译指南

FlightGear2016.4.1+VS2015编译指南 前言:本人之前也看了许多网上的教程,但编译一直出现各种问题(和操作系统位数,第三方库文件版本,VS版本,FlightGear版本都有一定的关系),花了两个星期终于编译成功了。因此整理了教程,希望能对大家有所帮助。 一、编译前准备工作 1、Cmake下载安装:上cmake官网https://https://www.360docs.net/doc/134406717.html,/download/下载CMAkE并安装,我用的版本是cmake3.6.3 2、OSG二进制文件下载:(自己编译也可以,但是耗时不说,还容易出现不兼容的问题),可以从官方的编译教程里面下载https://www.360docs.net/doc/134406717.html,/Building_using_CMake_-_Windows,如下图所示: 3、第三方库3rdParty及Boost下载:一样的也是从官方的编译教程里面下载(注意若要编译64位的程序要下载3rdParty.x64)https://www.360docs.net/doc/134406717.html,/Building_using_CMake_-_Windows,如下图所示:

4、simgear2016.4.1、flightgear2016.4.1源码和fgdata(程序启动时加载的地形、机场、飞机模型文件等都在这里面)下载:链接https://https://www.360docs.net/doc/134406717.html,/projects/flightgear/files/release-2016.4/,下载划线的三项,如下图所示: 5、构建编译目录:我在C盘下建立一个根文件夹FlightGear,然后把上面下载的编译所需文件的压缩包都解压到这个文件夹中,并新建两个文件夹:分别重命名为simgear-build和flightgear-build用来存放Cmake生成的可编译文件,如下图所示:(PS:plib和freeglut如果需要的话也可以自己去下载)

美国现役航空母舰详细介绍

美国现役航空母舰详细介绍 1,企业号(CVN-65)核动力航空母舰。 企业号航母是世界上第一艘核动力航空母舰,它的问世,使航空母舰的发展进入了新纪元。企业号是在1958年2月4日开工,1960年时下水,1961年11月25日正式完工服役。 该舰排水量85,600吨,全长342米,舷宽40米,最大甲板宽76米。武器装备为3座雷声(Raytheon)Mk298联装发射装置导弹、“北约海麻雀"(NA TOSeaSparrow)对空导弹、3座(GE/GD)Mk156管20毫米“火神密集阵”(V ulcanPhalanx)炮,。一般配备20架F-14“雄猫”(Tomcat)36架F/A-18“大黄蜂”(Hornet),4架EA-6B“徘徊者”(Prowler),4架E-2C“鹰眼”(Hawkeye),8架S-3A/B“北欧海盗”(Viking),4架SH-60F和2架HH-60“海鹰”(Seahawk). 服役35年来,“企业”号为美国海军立下了“汗马功劳”,多次被派往敏感地区和冲突地区,应付突发事件。1962年8月古巴导弹危机时,“企业”号曾参与美国海军封锁古巴的行动。1964年,…企业?号进行了史无前例的环球航行,途中无需加油和再补给,历时64天,总航程3多海里,充分显示了核动力的巨大续航力。越战期间,,“企业”号曾参与越战的空袭行动,并参与1975年的西贡撤退。1969年1月14日是“企业”号的灾难日,它的飞行甲板突然发生火灾意外并引爆9枚五百磅炸弹,飞行甲板被炸出三个大洞,内部也受创不轻,幸好在数小时抢救后扑灭火势并自力返航,之后的修复作业耗时三个月。2001年9月11日美国本土遭到恐怖份子猛烈攻击时,“企业”号正准备结束在中东的巡航返国,不过立刻被留在当地,并参与了日后阿富汗战争的“持久自由“(Operation Enduring Freedom)作战行动。这艘颠簸半生的“企业”号预定在2013年除役,被新世代核动力航空母舰CVNX的第一艘取代,届时“企业”号已在海上奔驰了52年。 2,尼米兹号(CVN 68) 航空母舰。

二战中的美国海军舰炮

战列舰主炮 在二战中,随着航空母舰的崛起,战列舰在海上作战的龙头地位被推翻了。但是战列舰在水面舰艇作战中还是起到了举足轻重的作用,他的主炮就是他的灵魂;同时他是支援两栖登陆作战的利器。 二战中美军共有10级26艘战列舰和战列巡洋舰在役,他们装备了406mm,356mm,和305mm三种口径的主炮。本文将分别对美国海军二战期间所使用的一些主要舰炮进行一个详细的介绍。 火炮炮管材质以及构成 Mark 7型406mm/50,装备于依阿华级战列舰。 这可能是所有在海军服役的最好的战列舰主炮。最初设计为发射较轻的1016公斤的Mark 5型穿甲弹,但在依阿华号开始建造前,他的装弹系统被重新设计以发射1225公斤的Mark 5型“特重”穿甲弹。这种穿甲弹的穿甲能力接近于日本大和级战列舰装备的460mm主炮,但是它的重量不到460mm炮弹的3/4。Mark 7型406mm炮所发射的穿甲弹能穿透9m的水泥,而它的高爆弹能制.造一个15m宽6m深的弹坑。Mark 7型406mm炮由膛管,身管,外管,和3层套管组成,采用了2道套管环,膛管身管环,炮尾环,和闩锁膛组成。部分组件采用了液压自紧技术制成,炮管镀铬以延长炮管寿命。使用了下启式Welin式断隔螺式炮闩。

正在组装上舰的Mark7型舰炮 等待组装中的炮管组件 型号:16英寸/50(406mm)Mark 7 设计时间:1939年 服役时间:1943年 炮重:108.5吨 全长:20.726米 管长:20.320米 膛线长度:17.344米 膛线:96条,3.88mm深 射速:2发/分钟 弹种:穿甲弹AP Mark 8 (1,225 kg) 高爆弹HC Mark 13 (862 kg) 射程:38720米(AP Mark 8) 38059米(HC Mark 13) 穿甲能力(侧装甲): 20000码(18228米):509mm

OSG虚拟可视化图形开发简介

OSG虚拟可视化图形开发简介 OSG诞生于大概是1997年,可以在osgChina[https://www.360docs.net/doc/134406717.html,]上查阅到关于OSG的来龙去脉。笔者使用OSG也已经有三到四年的时间了。当初偶然接触OSG到现在,OSG已经在国内外得到广泛的应用,国内已经有好几家专门使用OSG的公司,他们分布在杭州、西安、深圳以及还有一些我不知道的地方。然而,更让人兴慰的是国内的各重点院校与研究所都已经开始使用OSG。 我做为一直使用OSG做开发的图形工作者,感觉非常兴慰。当每一次在群里或论坛说OSG 又有什么什么消息时,看到很多人说:看来选OSG是选对了,OSG明天更好等等类似的话,我热泪盈框。OSG进入中国已经有七到八年了,在这期间,OSG经历了数次变迁,青丝变白发。使用OSG的开发者从无到有,从草根开发者到成立专门使用OSG的公司。 1.1 OSG简介 1.1.1 OSG的诞生 在1997年时,Don Burns由于喜欢滑翔机运动且对计算机图形学非常熟悉,在LINUX上写了一个控制滑翔机的小引擎,这便是OSG的最初雏形。后来在1998年,Don Burns在滑翔机爱好者邮件列表中遇到了Robert Osfield,对OSG的命运起到了决定性的改变。我们现在在邮件列表中也会经常看到Robert的名字,从98年至今,Robert一直担当OSG开发组长,权衡OSG的各种利弊。有很多人在刚开始接触OSG时感觉到非常痛苦,咋一看一点儿都看不懂,疑是什么鬼怪新语言。其实OSG是语法是标准C++的。您可以登录:https://www.360docs.net/doc/134406717.html,/ 与https://www.360docs.net/doc/134406717.html,查看关于OSG历史的更多信息。也可以查阅《OSG快速入门指南》[]的第一章的相关章节来获得OSG的发展更详细信息。 1.1.2 OSG在中国 OSG在2000年或更早时候进入的中国,据个人了解,FLMN在2003年接触的OSG,并在2005年创立了VRDEV[https://www.360docs.net/doc/134406717.html,]网站。VRDEV是国内OSG爱好者交流的中心,把无数OSG爱好者引入大门。3DVRI[https://www.360docs.net/doc/134406717.html,]是基于OSG的VR引擎,在大中院校及公司得到广泛的应用。关于3DVRI的相关案例可以查看osgChina的企业展示版面[https://www.360docs.net/doc/134406717.html,/projects/osgChina/enterprise.php]。在今年初二,由FreeSouth牵头,联合国内众多爱好者共同建立了OSG中国官方网站[https://www.360docs.net/doc/134406717.html,],以及OSG中国讨论区[https://www.360docs.net/doc/134406717.html,],组建了OSG在中国的大本营。 目前在国内使用OSG的大概有上千人,专做OSG相关项目的公司有三到五家。各高校与研究所与仿真相关的实验室等等都在不同程度的在OSG这个方向上投入人力与物力。您可以登录https://www.360docs.net/doc/134406717.html,查看OSG国内爱好者使用OSG的历程,也可以登录https://www.360docs.net/doc/134406717.html, 来查看最新的讨论。 1.2 如何学习OSG 1.2.1 OSG的书籍 OSG官方出过两本书,一本是《OpenSceneGraph参考手册》[OpenSceneGraph Reference Manuals],这本书有基于1.2与2.20双版本。该书大概成于07年六月左右,当时记得是在五一的时候,我当时正在家中吃饭,朋友通知说出书了。然而就在今天中午,3DVRI的唐先生刚刚打电话来告知喜讯,说他们方才已经购买到了这本书。这是我听到的第一个购买到这本书的相关消息。这本书是一本参考大全,大家应该有不少都看过C语言参考大全,C++参考大全,PowerBuilder参考大全。 换句话说,里面介绍的是函数与函数说明,并不涉及原理的讲述与案例。当然从某种意

美国海军现役主力战舰大全

. 美国海军现役主力战舰大全(2013版) 美国现役军舰(截止2013年7月15日) 共现役241艘主力战舰(不计算在建舰只) (辅助船只如普通补给船、运输船、油船、救援舰、海洋监视船、导弹跟踪船、医院船、导航船、发报船、扫雷艇、警备艇及三艘不退役战舰等近百艘舰船不计算在) 航空母舰(现役10艘,在建3艘) 一、杰拉尔德.R.福特级航空母舰(在建3艘)(满载10万吨) 1、CVN78 杰拉尔德.R.福特号 2、CVN79 约翰.F.肯尼迪号 3、CVN80 企业号 二、尼米兹级航空母舰(现役10艘)(满载10万吨左右) 1、CVN68 切斯特.尼米兹号 2、CVN69 德怀特.D.艾森豪威尔号 3、CVN70 卡尔.文森号 4、CVN71 西奥多.罗斯福号 5、CVN72 亚伯拉罕.林肯号 6、CVN73 乔治.华盛顿号 7、CVN74 约翰.C.斯坦尼斯号 8、CVN75 哈里.S.杜鲁门号 9、CVN76 罗纳德.里根号 .

10、CVN77 乔治.布什号 快速战斗支援舰(航母战斗群补给舰)(现役4艘) 一、供应级快速战斗支援舰(现役4艘)(满载49000吨) 1、T-AOE6 供应号 2、T-AOE7 雷尼尔号 3、T-AOE8 北极号 4、T-AOE10 桥号 巡航导弹核潜艇(现役4艘) 一、俄亥俄改级巡航导弹核潜艇(现役4艘)(水下18750吨) 1、SSGN726 俄亥俄号 2、SSGN727 密歇根号 3、SSGN728 佛罗里达号 4、SSGN729 佐治亚号 弹道导弹核潜艇(现役14艘) 一、俄亥俄级弹道导弹核潜艇(现役14艘)(水下18750吨) 1、SSBN730 亨利.M.威尔逊号 2、SSBN731 亚拉巴马号 3、SSBN732 阿拉斯加号 4、SSBN733 华达号 5、SSBN734 田纳西号

Contextcapture保姆级教程

Contextcapture保姆级使用教程 初学篇 1 新建工程 新建工程,设置工程路径 2 导入照片 导入本机照片。如需集群处理,则需要导入网络路径下的照片,详见6.2工程设置:

导入照片 Set downsampling(设置采样率):该参数只会在空三的过程中对照片进行重采样空三,建模时仍旧使用原始分辨率影像。 Check image files...(检查航片完整性):建模失败的时候可以用此功能进行数据完整性检查。 Import positions...(导入POS):导入POS格式如下, a.如果有多个照片组(Photogroup)则必须保证每个照片组中的照片名称唯一,否则会导入失败; b.POS路径必须为英文;

相机参数 每个照片组(Photogroup)都会有一个相机参数,可以在右键菜单中导入或导出相机检校参数(特别对CC4.4以后版本有用)。 3 空中三角测量 3.1常规空三流程 空三参数设置,如第一次使用,则建议直接按照默认参数,只需“下一步”即可,如欲了解其中参数意义则进入如下内容: (1)设置名称,最好根据飞行架次或项目信息进行设置

(2)参与空三的照片,默认使用全部照片。 (3)照片定位或地理参考设置

(4)空三参数设置,通常默认参数即可 a.对于地名拍摄照片,可能会修改“Keypoints density”、“Pair selection mode”、“Component construction mode”三个选项; b.对于航空拍摄照片,通常使用默认参数,如果多个架次且存在航高不一致的情况,则可能会修改“Pair selection mode”、“Component construction mode”两个选项;(实例:百里峡漂流两个架次航高不一致)

相关文档
最新文档