AppInventor加载3D模型 (1)OBJ文件及材质信息与简单动画演示

导入一个3D模型文件是一个3D引擎必不可少的功能,我们可以用多种方式实现3D模型文件的导入,本文将告诉大家在Scene3D引擎中如何加载3D模型文件。

一.准备工作

1.AppInventor平台(本文所使用的平台为wxbit)

Wxbit平台

2.Scene3D主程序

cn.zzq.Scene3D.Main.aix

3.Scene3D核心插件包

cn.zzq.Scene3D.Core.aix

4.Scene3D模型导入插件

cn.zzq.Scene3D.Plugin.Loader.aix

5.3D模型及纹理贴图

本文的目标将是成功加载如图所示中的所有文件


image

其中所使用到的AIX拓展包均可在我的上一篇文章AppInventor 3D引擎Scene3D最详细入门教程(1)找到下载地址。

二.方法/步骤

1.先将所下载的三个拓展包导入,如图将会出现9个拓展


拓展包

2.将如图所示的拓展组件拖入程序并拖入一个水平布局宽度高度设为充满,以此来充当3D世界的显示器。


image

建议再放置一个按钮做调试

3.首先,在Scene3D中,表现一个3D对象表面的色彩的信息叫做纹理(texture),纹理可以是图片,也可以是纯颜色,特别地,如果是图片作为的纹理又称作贴图(map)。
现在,我们需要定义一个添加纹理的函数,在Scene3D中,Texture是有关纹理的拓展组件,同时Texture也是一个纹理对象。TextureManager是一个管理纹理的拓展组件,如我们用CreateTexture函数创建好texture对象后需要用TextureManager拓展将纹理对象添加到纹理库,并且为纹理命名。在本篇文章中,我们需要加载一个3D模型,并为其加载贴图。由于手机的内存是有限的,所以我们需要导入的贴图一般也不会太大,我们希望的是通过一个给定的纹理名称,图片路径,纹理的大小实现创建并导入纹理到TextureManager中。注意:由于一些原因,在Scene3D中目前仅支持尺寸大小为2的整数次方的正方形的贴图,如64×64,128×128,256×256。

相关块介绍:
如下图,位于Texture拓展中包含了几个用于创建材质对象的块,其中CreateTextureByPicture块是较常用的块用于通过图片创建一个纹理对象,并自带图片压缩的参数,CreateTexture_1所创建的纹理对象使用贴图自身的尺寸大小,CreateTexture_0所创建的纹理对象是前者的useAlpha值设为来ture的版本。


image.png

如下图,是位于TextureManager组件中的几个块,AddTexture_1是我们较常用到的一个块,用于将纹理对象添加至纹理库中,并为其起个名字,ContainsTexture块是查找纹理库中是否存在指定名字的纹理,Flush块用于清空整个材质库。


image

之前提到,我们希望的是通过一个给定的纹理名称,图片路径,纹理的大小实现创建并导入纹理到TextureManager中。所以创建如下函数:


image.png

4.导入OBJ模型文件
首先,明确obj文件的概念:

OBJ文件是Wavefront公司为它的一套基于工作站的3D建模和动画软件"Advanced Visualizer"开发的一种文件格式,这种格式同样也以通过Maya读写。
OBJ文件是一种文本文件,可以直接用写字板打开进行查看和编辑修改。

如图,我们将camaro.mtl、camaro.obj、camaro.jpg导入素材库中,



使用如图的代码块做实验了解3D模型文件加载器Loader组件中的OBJ加载器LoadOBJ的返回结果是什么。


image.png

返回结果如图所示:


image.png

由上图结果可知,返回结果是一个列表,其中存放了若干个3D对象
我们将以上3D模型导入至世界中去观察一下,代码块如下图所示

image.png

代码块详解:
OnSurfaceCreated事件即Scene3D世界创始之初的初始化操作,
首先需要加载我们需要的Scene3D子插件,
Flush清空内存中未释放的材质,
在世界的原点创建了一个点光源,
调用LoadOBJ函数加载了3D模型输出的列表通过MergeAll合并为一个大3D对象(类似于Excel中的合并单元格或appinventor中的布局)
将大的3D对象添加到世界中,
用3D对象控制器绑定当前3D对象使其平移到手机屏幕前方5个单位长度(Scene3D的坐标系统采用右手坐标系统,即appinventor画布对应的x,y轴方向,z轴垂直屏幕向里)。

手机界面如图所示:


为了方便360度全方位观看3D模型,我们需要在3D显示布局里添加一个充满布局的画布用于捕获手势,代码块如图所示:


image.png

这样便成功可以用手势控制3D模型的旋转了


image.png

这便成功加载了OBJ的3D模型文件,下一步将为其添加纹理。

5.为OBJ文件添加纹理
调试查看当前材质库有何材质,代码块如下:


image.png

显示结果如下:


image.png

由图可知,当前纹理库共有两个纹理,名称分别为--dummy--和camaro.jpg其中--dummy--是Scene3D默认自带的纹理,是个纯白色的纹理,camaro.jpg是我们在导入OBJ文件时导入的mtl材质文件中记载的纹理信息,在Scene3D中mtl文件的导入仅会导入贴图名称和颜色信息,具体的贴图文件需要我们自己设置,代码如图,我们仅需在初始化阶段加载如图代码块来替换纹理,然后我们设置3D对象的纹理名即可

替换纹理
绑定纹理

手机显示结果如图,
显示结果

现在我们就成功设置了纹理贴图,大家可能会有疑问,为什么车轮的位置这么诡异,实际上,之前我们导入OBJ文件时返回的是一个列表,其中有5个3D对象,其实是有4个车轮和一个车身所组成的,那么我们接下来的目标就是调整车轮的位置。

6.调整车轮位置
首先我们需要了解OBJ文件的结构,我们尝试打开obj文件,如图所示


image.png

image.png

我们会发现OBJ其实就是一个ASCII编码的文本文件,是可以直接被阅读的,其中直接以文本形式记载了一个3D模型的顶点,法向量等数据,并且可以放置多个3D对象,每个3D对象以o打头,后跟该3D对象的名称,我们想要分别获取车身和四个车轮。
在3D对象控制器中可以获取某个3D对象的名称,封装为函数如图所示,


image.png

注意:由于引擎在世界控制器WorldHandler存在有GetObject3DByName块,用于通过名称获取3D世界中的3D对象,所以尽量不要使两个相同世界中的不同的3D对象使用同一name值,以防止意外情况发生,在Scene3D引擎中,每生成一个3D对象,都有一个ID值与其对应,默认导入的Name将会以"obj文件中3DdD对象名_JPCT+ID"来命名,使用纯代码创造的3D模型将以“object+ID”形式命名。

所以,我们将通过如图的代码选择出车身和车轮的Object3D对象并删除之前的合并对象的代码(前左为lf,前右为rf,后左为lr,后右为rr)


image.png

添加一个函数,方便设置车轮的位置


image.png

添加一个函数,用于将若干个3D对象与一个3D对象绑定,成为3D对象的一部分(子对象或孩子),将会继承父对象的所有变换

如图的代码块,设置了四个车轮的坐标(局部坐标),并且将车轮作为车身的一个子对象(孩子),然后将所有对象添加至世界中,至此整个OBJ模型文件完美导入。


image.png

运行结果:


image.png

7.添加车轮动画
至此,OBJ模型文件的导入已讲解完毕,那么可能会有人问了,为什么3D建模工具在完成模型的创建后不直接把所有的模型合并呢?其实,将模型的零部件分离是有许多好处的,比如我们本节要讲解车轮动画。
通过如图的代码,我们可以控制前轮的旋转


image.png

通过如图所示的代码,我们可以控制车轮的转动


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343