C++基础知识–多态【For Maya plugin】

C++基础知识–多态
什么是向上映射
将派生类的对象、引用或指针转变为基类对象、引用、指针的活动被称为向上映射。
为什么被称作向上映射,而不是向下、向左、向右映射?
类继承关系图的传统画法中通常都是将基类画在上层,将派生类画在下层。例如:
Base
|
Derived
为什么能够向上映射
向上映射总是安全的。因为是从更专门的类型映射到更一般的类型——对于这个类接口可能出现的唯一的情况是它失去成员函数或者成员变量,而不会增加它们。这就是编译器允许向上映射而不需要显式说明或者作标记的原因。
向上映射的危机
看例子:
class base{
public:
void print(){
cout<<"base class"<print();
}
在上面的代码中,我们希望得到派生类指针所指内容print(),但是编译器却以指针的类型为主要参考依据,返回了基类的print()。如何避免这样的危机,而让指针能够根据地址取值而不是根据类型取值呢?
为什么会存在向上映射的危机?
因为:早绑定(静态绑定)
解决之道:晚绑定(动态绑定)|虚函数
Polymorphism allows a client to treat different objects in the same way even if they were created from different classes and exhibit different behaviors.
动态绑定的实现机制(三步)
1为每一个包含虚函数的类设置一个虚表(VTABLE)
每当创建一个包含有虚函数的类或从包含虚函数的类派生一个类时,编译器就会为这个类创建一个VTABLE。在VTABLE中,编译器放置了这个类中,或者它的基类中所有已经声明为 virtual 的函数的地址。如果在这
个派生类中没有对基类中声明为 virtual 的函数进行重新定义,编译器就使用基类的这个虚函数的地址。而且所有VTABLE中虚函数地址的顺序是完全相同的。
2初始化虚指针(VPTR)
然后编译器在这个类的各个对象中放置VPTR。VPTR在对象的相同的位置(通常都在对象的开头)。VPTR必须被初始化为指向相应的VTABLE。
3为虚函数调用插入代码
当通过基类的指针调用派生类的虚函数时,编译器将在调用处插入相应的代码,以实现通过VPTR找到VTABLE,并根据VTABLE中存储的正确的虚函数地址,访问到正确的函数。

看完不过瘾?点此向作者提问

MR的批渲染问题

还有一个问题,批渲染时如果使用MR渲染,命令行该如何写?
我设置好了,批渲染时系统会自动地用默认的渲染器渲染.
我看了一下帮助 /R 可以挑选渲染器,我写了以后还是不行,是不是我写得有错误?

看完不过瘾?点此向作者提问

Maya Render layer问题

豪老大,Maya中Render Layer中建立的Shadow层,这个层相关的节点在那里,我找不到,其他的渲染层都可以看到相关节点被建立.
当我的场景复杂的时候,阴影层总是会出错,阴影层渲染不出来,或者是显示错误,一直找不出原因,也找不到管理这个层的节点.

看完不过瘾?点此向作者提问

用Maya表达式Fake背景

用Maya表达式Fake背景—连接贴图的摄像机
如图,如果把带有Alpha通道的树木的纹理贴到NURBS平面上,复制并摆放这些平面,可以很快的得到一片树林。使用这种方法可以很快的Fake出树林的背景。

但是问题随之而来,如果此时转动或移动摄像机,就会穿帮,因为树木是贴在一个NURBS平面上的,而不是真正的3维树木。即这些NURBS平面必须时刻正对着摄像机,才能保证场景的以假乱真。
如何让这些平面时刻正对着摄像机,即使移动旋转摄像机也不会穿帮呢?下面介绍制作方法。
执行Create | Cameras | Camera,创建一个新的摄像机,默认情况下该摄像机是在原点,不要移动摄像机,可在top视图菜单中执行Panels | Perspective | camera1,将top视图切换为摄像机视图。摆放NURBS平面,并查看摄像机视图中的最终结果,如图。

选择所有NURBS平面,按W键,激活移动工具,然后按Insert键,进入Pivot调整模式,如图。

按住x键不放,拖曳中键到原点,将这些NURBS面的Pivot都移动到原点,因为摄像机也在原点,所以此时所有NURBS面的Pivot与摄像机的Pivot重合,如图。

再次按下Insert键,进入普通的移动模式。选择NURBS面,查看他们的Pivot,应该都在原点。选择所有的NURBS面,执行Modify | Freeze Transformations,如图,将他们的变换参数都规零。

Freeze Transformations之后,这时你会发现所有的NURBS面的变换参数与摄像机的变换参数完全一样,对了,下面将使用表达式(Expression)建立摄像机与NURBS面的联系,使NURBS面跟随摄像机变换。
执行Window | Animation Editors | Expression Editor,如图,打开表达式编辑器。

假设某个NURBS面的名称为obj,而新建摄像机的名称默认为camera1,则在表达式编辑器中输入如下表达式:
obj.tx = camera1.tx;
obj.ty = camera1.ty;
obj.tz = camera1.tz;
obj.rx = camera1.rx;
obj.ry = camera1.ry;
obj.rz = camera1.rz;
即可使该NURBS面跟随摄像机运动了。
当然这里需要对每个NURBS面添加表达式。使用各个NURBS面的实际名称替换上面的obj即可,如图。

添加完表达式之后,移动旋转摄像机,发现这些NURBS面已经可以跟随摄像机变换了,并且时刻正对着摄像机,这正是我们要的效果。相当与我们把贴图与摄像机连接了起来,制作了多个Image Plane。

看完不过瘾?点此向作者提问

Maya中Blind Data的使用 [For Game] [游戏]

Maya中Blind Data的使用 [For Game]
MAYA的高级用户或者使用MAYA制作过游戏的朋友,应该听说过Blind Data。Blind Data是一种特殊的数据,用来为多边形的顶点、边、面或NURBS片面赋值,从而标记物体的顶点或面的属性,把模型输入游戏引擎中,Blind Data可以被游戏引擎所识别。例如游戏中的角色碰到墙上的一个装置,可以打开大门;或者角色接触到某个物体,可以增加生命值/增加血液等,而接触到另一个物体则减少生命值/减少血液等,我们可以使用Blind Data来标记这些物体或者物体的某一部分。下面我们介绍Blind Data的用法。
MAYA中对Blind Data的操作集中在 Window | General Editors | Blind Data Editor,如图。

下面我们准备新建一个有益物体的模板,当游戏引擎中的角色接触一个物体的不同面,可以获得不同的经验值或增加不同的生命力。
执行Window | General Editors | Blind Data Editor,打开Blind Data编辑器,如图.
单击Type Editor标签,默认的ID为0,在Name后输入helpfulTemplate,在Association Type下选择Face,在Long name下输出helpful,在Short name下输出help,Data Type选择double,如图,然后单击下面的New Preset按钮,增加该ID为0的helpfulTemplate型的Blind Data的预设值。

值得说明的是Association Type下有Object、Face、Vertex三个选项,选择Object,可以设置整个物体为有益或有害;选择Face,可以设置物体的某一个或多个面有益或有害;选择Vertex,可以设置物体的一个或多个顶点有益或有害。大家根据具体的游戏设置来选择Blind Data的类型。
如图,在Preset Name下输入helpPreset,在helpful下输入默认值0.0,然后单击左侧的Save按钮,保存该类型的Blind Data。

此时,在左侧的白框中会出现helpfulTemplate(0)的字样,表明ID为0的helpfulTemplate型的Blind Data已经创建成功,如图。如果此时要创建其他类型的Blind Data,可以按左侧的New按钮,继续创建其他ID的Blind Data。

在Blind Data编辑器中单击Color/Query标签,勾选第一行左侧的小勾,然后在Tag/ID栏中按住右键不放,在弹出的菜单中选择helpfulTemplate,正是刚才我们设定的Blind Data模板,如图。

之后,勾选Long Name下的helpful,如图,此时MAYA会自动增加一栏Select Value,设置类型为Continuous,如图,并可以根据个人喜好或者游戏设定设置Min和Max的色彩。

单击Blind Data编辑器中的Apply标签,如图,可以看到左侧的白框中有helpfulTemplate(0)的字样,选择它,可以看到右侧出现了该类型Blind Data的详细信息,并可以设置helpful的具体值,勾选下方的Color data on apply。

执行Create | Polygon Primitives | Cube,创建一个多边形方块,在方块上按住右键不放,在弹出的标记菜单上选择Face,然后选择某个面,在helpful为0的状态下,单击Blind Data编辑器下方的Apply按钮,为该面赋予Blind Data,如图。

在Blind Data编辑器中修改helpful值为0.2,然后选择方块的另一个面,单击下面的Apply按钮,为其赋予Blind Data;然后分别修改helpful为0.5、0.8、1等,分别赋予方块的其他几个面。最后查看方块,根据颜色可以很容易的判断每个面的Blind Data大小,如图。如果要去除Blind Data的色彩显示,可以单击Blind Data编辑器窗口下方的Remove Color,即可去除Blind Data的颜色显示。

看完不过瘾?点此向作者提问

Maya中顶点着色(Vertex Color)的三种方法

Maya中顶点着色(Vertex Color)的三种方法
MAYA中多边形的顶点(Vertex)着色,使用的是与材质无关的另外一套数据信息,这些顶点色彩与几何体存储在一起,可以导出到游戏引擎或其他软件中。但使用Maya Software渲染器无法渲染出设定的顶点颜色,如图。

图 基于顶点(Vertex)的着色与材质无关
MAYA中有三种方法可为顶点着色,下面分别介绍。
第一种方法是,首先选择多边行的一个或多个顶点,在Polygons模块下执行Color | Apply Color,如图,打开其选项窗,选择色彩,单击Apply Color按钮,为所选顶点应用色彩。

也可以一次性为多个顶点应用色彩,如图。

图 一次性为多个顶点Apply Color(应用颜色)
第二种方法是使用Paint Vertex Color Tool(绘画顶点颜色工具)在顶点上直接绘画颜色。选择多边形,执行Color | Paint Vertex Color Tool,如图,打开其选项窗,设置色彩和画笔半径大小,直接在多边形绘画,即可为该顶点的顶点着色了。

为顶点着色时,使用Paint Vertex Color Tool在绘画过程中可以随时切换画笔大小、画笔颜色,如图,有时这比选择顶点执行Color | Apply Color要直观、方便。

图 绘画顶点颜色
第三种顶点着色的方法是Prelight,即预亮,我们将在下面单独介绍。
Prelight与Bake
Prelight,预亮,也可以为多边形顶点着色。Prelight基于多边形的每个顶点,对光照和纹理执行渲染计算,把光照和纹理信息转换为每个顶点的颜色信息,并把顶点颜色与几何体存储在一起。这样多边形的顶点色彩就与材质、灯光无关了,所以即使删除场景中灯光和模型的材质纹理,模型表面色彩也不会改变。这样即使把模型输出到其它平台中,灯光和纹理信息仍然在。如果需要将MAYA模型转换到游戏开发平台中时,Prelight很有用。
值得说明的是,由于Prelight是基于顶点进行的,顶点色彩是和材质无关的另外一套数据信息,所以Prelight的结果不会被渲染出来。
Prelight之前,场景中至少要有一个灯光,但对被计算的灯光的最大数量没有限制。
如图,选择已经赋予贴图的多边形,执行Color | Prelight(Maya)。

如图,对比两个多边形球,查看Prelight的效果。

此外,Prelight信息无法被删除,但可以使用Color | Apply Color,使用Apply Color下的Remove选项,间接移除Prelight结果。
MAYA中和Prelight类似的概念就是Bake(烘焙)了。Prelight是基于模型的顶点,把光照和纹理信息转换为每个顶点的颜色信息,与几何体存储在一起,Prelight得到的数据信息和材质无关,无法被MAYA的渲染器渲染出来。而Bake(烘焙)是基于模型表面上的每个可视点来进行的,Bake(烘焙)的结果是可以被渲染的。MAYA的Bake(烘焙)原理是将模型的材质节点网络(3D纹理、凹凸等)和物体接受的光照信息一并Bake为一张2d纹理贴图。Bake(烘焙)的方法是,依次选择模型的材质(可在Hypershade中选择)和模型,然后在Hypershade中执行Edit | Convert to File Texture(Maya Software),如图。

看完不过瘾?点此向作者提问

Maya的法线贴图应用(Normal Map)

Maya的法线贴图应用(Normal Map)
在CgTalk网站评选的2004年CG大事TOP 10中, 第六件大事便是“法线贴图成为游戏行业主流”,CgTalk上对法线贴图描述如下:
法线贴图用于非交互3D渲染已不是什么新技术了,但游戏上的应用还是最近才出现的事。在 Doom 3 (id software)、Half Life 2 (Valve Software)、Halo 2(Microsoft)和 Thief 3:Deadly Shadows (Eidos Interactive)等04年的几款游戏大作中,法线贴图为实时交互领域带来了前所未有的真实体验,如图。

法线贴图是一种利用含有法线信息的纹理来制作低多边形模型的方法。凹凸贴图(Bump)与之有着相似的概念,但是法线贴图的优势在于即使在灯光位置和模型角度改变的情况下,依然可以得到正确的shading,从而为低多边形模型带来更多的细节效果。
凹凸贴图(Bump)通常使用单通道图像(灰度图像)来计算,而法线贴图使用多通道图像(RGB)来体现法线信息。凹凸贴图改变的是法线向量的大小,而法线贴图能同时改变法线向量的大小和方向。
下面我们介绍如何在MAYA中制作法线贴图。
如图,为同一个模型准备一个低模,一个高模。在高模的表面可以有很多细节。

将低模和高模放在相同的位置,然后在Rendering模块下执行Lighting/Shading | Transfer Maps,如图。

在弹出的窗口中,设置Target Meshes为低模,Source Meshes高模,分别在Outliner中选择相应的模型,使用Add Select按钮添加。之后单击Output Maps标签下的Normal,即选择输出法线贴图。然后在下面设置贴图存储路径和名称,设置法线贴图的格式,这里我们选择FF格式。其他参数如图,最后单击最下面的Bake按钮,即可生成法线贴图了。注意法线贴图的存储路径和名称不要含中文,否则会出错。

最后我们生成的法线贴图,如图。

打开Hypershade,MAYA会自动将生成的法线贴图作为凹凸贴图连接到一个Lambert上,并赋予低模,如图,注意这里Bump Map的Use As选项是Tangent Space Normals,而不是以前常用的Bump。

渲染,如图,体会法线贴图与普通的Bump贴图的不同。

看完不过瘾?点此向作者提问

用Maya MEL查询骨骼影响的多重点【for game】

用Maya MEL查询骨骼影响的多重点【for game】
在游戏公司,这个MEL会有用。
在使用Smooth绑定时,模型上的某一个顶点,可能被多个骨骼同时影响,笔者称这样的顶点为“多重点”。有时在游戏制作中,我们需要将这样被多节骨骼同时影响的多重点找出来。
如图,选择骨骼和圆柱,执行Skin | Bind Skin | Smooth Bind,将三节骨骼和该多边形圆柱绑定起来。

然后将圆柱命名为“obj”,如图,简短的名称便于后面使用MEL时快速的输入。

执行如下MEL,即可以显示圆柱上同时被三节骨骼影响的顶点,如图。

当findVertex Proc执行过一次后,后面只需要输入函数即可,不需要再次执行proc了。
输入
findVertex("obj",1);
即可显示同时被两节骨骼影响的顶点,如图。

输入
findVertex("obj",2);
即可显示只被一节骨骼影响的顶点,如图。

该MEL的实现思路主要是使用skinPercent命令,查询某个顶点被某个骨骼的影响权重。该权重为0,则认为该顶点不受该骨骼影响;该权重不为零,则认为该顶点被该骨骼影响。具体的MEL代码如下:
/////////////////////////////////////////////////
//create by Lizhihao at 2007.4.18
//用法:输入已经Smooth绑定的多边形模型名称,和一个整数,执行
//proc findVertex(string $objName, int $n)
//参数说明:——-模型名称——–多重点——
//假设绑定模型上有N节骨骼,则输入n,可以显示被(N-n)节骨骼同时影响的顶点
//例如输入0,则可显示N重点
////////////////////////////////////////////////
proc findVertex(string $objName, int $n){
select -cl;//clear selection list
int $vertexCount[] = `polyEvaluate -v $objName`;
string $skinName=`findRelatedSkinCluster($objName)`;
string $jointName[] = `skinCluster -q -wi $skinName`;
int $jointCount = size($jointName);
float $weight[];
int $index_vertex;
int $index_joint;
int $FLAG;
int $sum_flag = 0;
for( $index_vertex=0; $index_vertex < $vertexCount[0]; $index_vertex++){ string $currentVertex = $objName + ".vtx[" + $index_vertex + "]"; for( $index_joint = 0; $index_joint < $jointCount; $index_joint++){ $weight[$index_joint] = `skinPercent -transform $jointName[$index_joint] -query $skinName $currentVertex`; if( $weight[$index_joint] > 0) $FLAG = 1;
else $FLAG = 0;
$sum_flag += $FLAG;
}//end for $index_joint
if( $sum_flag == ($jointCount – $n) )
select -add $currentVertex;
$sum_flag = 0;//clear $sum_flag
}//end for $index_vertex
}//end proc
//run proc
findVertex("obj",0);

看完不过瘾?点此向作者提问

恶搞Maya | MAX的广告

//我们反对恶俗广告,但我们坚决誓死捍卫他播放恶俗广告的权利。
======================
关键是品牌。自从盗版使用了ADSK生产的Maya2008之后,做起动画来腰也不酸了,手也不疼了,连续做八小时动画也不费劲,连动画质量也翻番了,半个小时就能做出个华南虎出来~[face06]
======================
奔驰的华南虎——–让一切都动起来,Maya2008!
======================
Autodesk白加黑,早上MAX不瞌睡,晚上Maya睡的香[face18]

看完不过瘾?点此向作者提问