手机3D已经相当流行,现在将学习到的信息进行总结一下:
一般来说,M3G支持两种3D模式:立即模式(immediate mode)和保留模式(retained mode)。
怎么来获取数据文件?
Object3D[] objects = Loader.load("file.M3G");
Object3D[] objects2 = Loader.load(byteArray, offset);
他们均返回一个对象数组,即为三维动画数据。
有了这个信息,我们来寻找数据中的世界节点:
private void loadWorld()
{
try
{
Object3D[] buffer = Loader.load("/res/map.M3G");
for(int i = 0; i < buffer.length; i++)
{
if(buffer[i] instanceof World)
{
world = (World)buffer[i];
break;
}
}
buffer = null;
}
catch(Exception e)
{
System.out.println("Loading error!");
reportException(e);
}
}
获取到世界节点,下边我们可以进行处理数据对象了。
获取照相机对象:
private void loadCamera() {
if (world == null)
return;
cam = world.getActiveCamera();
Light l = new Light();
l.setMode(Light.AMBIENT);
l.setIntensity(3.0f);
world.addChild(l);
}
注意:上放代码在世界节点增加了光照效果。另外,照相机可以与世界节点同级别,可以通过下边的代码来创建。
Camera cam = new Camera();
cam.translate(3.0f, 0.0f, 3.0f);
现在来看一下怎么处理我们获取的照相机对象:
private void moveCamera() {
if (key[LEFT]) {
camRot += 5.0f;
} else if (key[RIGHT]) {
camRot -= 5.0f;
}
cam.setOrientation(camRot, 0.0f, 1.0f, 0.0f);
double rads = Math.toRadians(camRot);
camSine = Math.sin(rads);
camCosine = Math.cos(rads);
if (key[UP]) {
// Move forward
cam.translate(-2.0f * (float) camSine, 0.0f, -2.0f * (float) camCosine);
headDeg += 0.5f;
cam.translate(0.0f, (float) Math.sin(headDeg) / 3.0f, 0.0f);
} else if (key[DOWN]) {
// Move backward
cam.translate(2.0f * (float) camSine, 0.0f, 2.0f * (float) camCosine);
headDeg -= 0.5f;
cam.translate(0.0f, (float) Math.sin(headDeg) / 3.0f, 0.0f);
}
}
对于左右方向的旋转,我们使用照相机的函数(相对固定y轴):
setOrientation(f,f, f,f);
对于前后方向的移动,我们使用照相机的函数(为了效果,我们记录旋转的角度,x、y、z均变动):
translate(f, f, f);
好了,获取到了世界节点,并且可以简单的进行动画的移动处理。
如何来绘制,展现于手机上呢?
Graphics3D g3d = Graphics3D.getInstance();
g3d.bindTarget(g, true, RENDERING_HINTS);
g3d.render(world);
最后不要忘记了:
g3d.releaseTarget();
好了,在建立一个运行的线程,监视移动中的画面变动。
程序结束。
整体的思路是:
我们可以通过读取一个m3g文件来获取三维数据,然后可以通过这些数据找到我们需要的信息,当然,最重要的是World数据,有了它,我们可以加入对他的处理。
因为通过World可以获取到Camera,然后通过Camera的移动来改变角度,是我们产生3D的感觉。当然你也可以加入光照、纹理、网格等信息,来达到不同的效果。
在通常的Graphics中,我们只处理二维图形,处理三维的应该使用Graphics3D,我们可以通过Graphics3D.getInstance()来获取,然后将其与World进行绑定。
思路顺了,一切OK。
参见原文
:https://developer.sonyericsson.com/site/global/techsupport/tipstrickscode/mobilejava3d/p_java3d_tutorial_part1_compliments_redikod.jsp
分享到:
评论