目前安卓ios上的商城项目非常多,而体验来体验去,商品的展示无非就是图片,毫无新意可言,
如果将商品通过3d模型展示出来,那绝对让人耳目一新
本人最近在研究关于android上展示3d模型一些方案,通过对比,最终选择了jpct这款。本文不会对具体的集成做具体介绍,因为官网上的demo已经能够很清晰的将模型展示出来。本文仅仅记录自己在集成过程中所遇到的问题:
1, jpct支持多种格式的3d文件:通过Loader这个类中的一系列静态方法进行3d文件的读取加载,
Loader.loadOBJ(obgS, mtlS, 0.08f);
2, 以obj格式的3d文件为例,调用
Object3D objs[]=Loader.loadOBJ(obgS, mtlS, 0.08f);会得到一个Object3D的数组,Object3D就代表着一个3d模型,而一个obj文件中会包含多个模型,
所以加载出来会是一个Object3D数组
3, 由于对Object3D的移动,旋转,缩放等操作是独立的,就是说,如果一个World中存在多个Object3D的话,这些移动,旋转,缩放的操作很可能时这些加载
出来的对象混乱掉,这时需要做的是将数组的一个Object3D作为parent,其他的作为这个parent的child就行了,具体的api就是调用mainObj.addChild(obj);
4, 对于旋转的情况,既可以旋转Camera也可以旋转Object3D本身,而对于旋转Object3D的情况,需要注意的是旋转轴的设置,这个库中有对于的api通过 设置mainObj.setRotationPivot(SimpleVector.ORIGIN);可以将某一个物体设置到原点的位置,但是对于一个Object3D如果存在子Object3D的情况可以 获取各个Object3D的RotationPivot,然后进行相加即可,需要注意的是mainObj.setRotationPivot(SimpleVector.ORIGIN);这个api的调用必须是在
mainObj.build();调用之后
5, 关于材质的加载:
在obj类型的文件加载的时调用如下 Object3D objs[]=Loader.loadOBJ(obgS, mtlS, 0.08f);其中第一个参数是obj文件流,第二个参数是mtl文件流,这两个文件
都是通过文本文件,可以直接通过文本编辑器打开查看,其中mtl就代表着材质的相关信息,虽然如此,我们还是需要注意的是材质不是说仅仅设置了这个
mtl就行的,我们打开mtl文件会看到如下:
newmtl BodyA illum 2 Kd 1.0 1.0 1.0 Ka 1.0 1.0 1.0 Ks 0.0 0.0 0.0 Ke 0.0 0.0 0.0 Ns 0.0 map_Kd BodyA1_0.png newmtl BodyB00 illum 2 Kd 1.0 1.0 1.0 Ka 1.0 1.0 1.0 Ks 0.0 0.0 0.0 Ke 0.0 0.0 0.0 Ns 0.0 map_Kd BodyB1_0.png newmtl BodyB01 illum 2 Kd 1.0 1.0 1.0 Ka 1.0 1.0 1.0 Ks 0.0 0.0 0.0 Ke 0.0 0.0 0.0 Ns 0.0 map_Kd BodyB1_0.png每一个 newmtl 代表着一个新的材质,而
map_Kd后面的值代表材质图片,但是这个材质图片并不会自动去找,本人最开始以为,这个值如果给定一个绝对路径那么jpct框架会自动找到这张图片,经过试验
发现是错误的,其实这里的图片例如以上代码中的:BodyA1_0.png、BodyB1_0.png仅仅是代表TextureManager所维护的材质的key-value中的key,在解析这个mtl
文件的时候会在TextureManager中添加所解析到的材质,但是添加的仅仅是材质的引用而已,至于这个引用能不能引用到材质,需要看我们是不是已经添加到内存中。
我们需要在渲染3d图像之前就将这些材质加载到内存中:调用如下api:
Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.loadImage(new FileInputStream(baseDir + name)), 256, 256)); if (!TextureManager.getInstance().containsTexture(name)) TextureManager.getInstance().addTexture(name, texture);这个name必须与mtl里的map_Kd保持一致比如上例中的:
map_Kd BodyB1_0.png其中的name必须与BodyB1_0.png保持相同,才会在渲染的时候加载到这个材质