- 浏览: 809972 次
- 性别:
- 来自: 广州
最新评论
-
mixture:
语句int num1, num2;的频度为1;语句i=0;的频 ...
算法时间复杂度的计算 [整理] -
zxjlwt:
学习了。http://surenpi.com
[问题解决]Error: ShouldNotReachHere() [整理] -
Animal:
谢谢 楼主 好东西
算法时间复杂度的计算 [整理] -
univasity:
gaidandan 写道缓存失败,,模拟器上可以缓存,同样代码 ...
[开发总结]WebView使用中遇到的一些问题&解决 -
blucelee2:
那么麻烦干吗,而且这种方法会导致,当拉太小的时候样式会丢掉,整 ...
[SWT]SashForm中固定单侧大小(&实现面板隐藏)
<!-- 整理收集自网络,收藏以便日后查阅 -->
Introduction to Light 3D theory and orientation
This is the second part of the JSR 184 (M3G) tutorial. Here I'll go through some very basic 3D theory, 3D math and then finish the lesson with a simple orientation demo. Here are also all the links from the last tutorial, just in case you get lost: First of all, and probably most importantly, the dedicated Mobile Java 3D web section on Sony Ericsson Developer World. Second, if you ever get stuck, go to the Sony Ericsson Mobile Java 3D forum . For everything else, use the Sony Ericsson World Developer web portal , there you will find the answers to your questions and more. The goal of this tutorial is to give you a good enough understanding of 3D math for you to be able to utilize JSR 184's translation and orientation methods. I'll go through 3D coordinate systems, translation in 3D space and orientation around a vector. Also, you'll be able to use this newfound knowledge at the end of the tutorial to rotate meshes in code and place them in 3D space. This will however be far from any kind of reference, hence the title "Light 3D theory and orientation". Later chapters of this tutorial series will contain more advanced topics. Since the code is meant for educational purposes it isn't optimal, nor does it cover all the errors you might encounter while programming in 3D. |
What you should know
Before you start reading this, you should have read the first
tutorial of this series and should have a basic understanding of
Calculus and Linear Algebra. It isn't necessary to know the math but it
will surely help understanding.
3D coordinate system
The three dimensional coordinate system is a lot like the two
dimensional, except the addition of another axis. This axis, the z-axis,
is also usually called the depth.
2-Dimensional coordinate system. |
3-Dimensional coordinate system. |
As you can see from the pictures above, in 3D the objects don't just
have width and height (x, y) but also depth (z). Thus, a point on a
three-dimensional object is always defined with three coordinates, the
x, y and z. 3D objects consist of an array of points (vertrices) that
define the faces of the model. A cube has eight corners and thus eight
points (although a lot of them are shared). So coordinates for a cube
could be (in x, y, z order):
Front face: -1.0, -1.0, 1.0 -1.0, 1.0, 1.0 1.0, -1.0, 1.0 1.0, 1.0, 1.0 |
Back face: -1.0, -1.0, -1.0 -1.0, 1.0, -1.0 1.0, -1.0, -1.0 1.0, 1.0, -1.0 |
Above we have the points of a cube with its center point in Origo (0, 0, 0). Also note how the back face is identical to the front face, apart from the z (depth) coordinate which is positive 1 for the front face and negative 1 for the back face. If you think about it, it's logical. Since the z-axis is also called depth it's only logical that the back face has a negative depth.
However, even if the above are all the points that are needed for a cube, we also need to know the faces. The 3D rasterizer doesn't know what to do with simple 3D points, as they can be turned into pixels, thus resulting in 8 pixels being drawn on screen, when we actually want a cube. This is where faces come in. An object has its list of points (just like above, for the cube) which its faces consist of. A face is a surface of a 3D model that's made up of 3 or more points. Usually all models consist of a large number of triangulated faces, that is, every face is a triangle consisting of 3 points. So, for instance, our cube would need two triangles for each side (since two triangles make up a quad) and the cube has 6 sides so we'd end up with 6*2 = 12 triangles. Since each triangle needs 3 points we'd ultimately need 12 * 3 = 36 points to define our cube. That's a lot more than the original 8 points, isn't it? However, that isn't the whole story. As you might understand already, a lot of those 12 triangles would be sharing the same points – as shown by the illustration to the right. |
As you can see, the point labeled "Point 1" is actually
shared by Face A and Face C. So we don't really need to store all 36
points. In fact, the first eight points are enough, stored in an array,
and then let the triangles hold indices into our vertex array. This way
we save a whopping 36 - 8 = 28 points. For complex models this number is
even greater. To the right is a picture that illustrates the vertex
array and triangle indices. In case you haven't noticed, the face displayed is the same Face A from our cube and all the eight points in the vertex array are our eight cube points. As you see, each triangle doesn't have to store three points consisting of three coordinates each, for a whopping nine float variables per triangle. Instead, each triangle only holds three indices per triangle, which makes it a measly three integer variables per triangle. That's a big cut in memory use, especially if you are making models of 300 triangles or more. |
Orientation and Translation
Every point in a model is rotated and translated from its own (object)
coordinates into the global (world) coordinates. This is so that we can
actually display them at any point in the 3D universe, and not just
where they were created. (For reference, most models are created around
their own local origo. If we didn't translate models to world
coordinates we'd always render everything in the origo of our world.
Boring!).
So this translation business is obviously pretty important. How is it done, you ask? It's rather simple, really. All you need to do to move a model, is to simply translate all its points. For instance, our cube in the example above was created around its own origo but we want the cube to be displayed at coordinates 10.0, 0.0, -10.0. That's 10 units to the right and 10 units deep. To do this we just simply go over our vertex array and just add 10.0 to the x coordinate of each point and deduce 10.0 from the z coordinate of each point. Simple!
If you remember the first tutorial, we translated our camera to move around in the world. The camera can also be seen as a 3D object, so what we did there was just add or subtract from the camera's point coordinates to move it.
Normally, we want to rotate our objects as well. Rotation is a bit harder to understand than translation since it's more complex in nature. Let's quickly glance back at our picture of the cube, now slightly modified to the right: As you see, an object in 3D space can be rotated around one of the three axes. Rotation around the y-axis is also called the yaw, rotation around the x-axis is called the pitch and rotation around the z-axis is called the roll. However, in this tutorial I'll call them rotations around whatever axis I'm talking about, to keep things simple. |
Rotation around an axis is best visualized by taking a cubic piece of cheese. (Yes, please go and get a small piece of cheese from the fridge, and bring three toothpicks as well.) This cheese will resemble our cube. Now, by piercing the cheese with a toothpick where the axis you wish to rotate around is, and spin the toothpick, you will get rotation around an axis. Rotation around an axis is always performed counter-clockwise for positive degrees and clockwise for negative degrees.
Rotation of a 3D object is really pretty easy, as you can rotate an object around your three axes and that's it... or is it? First of all, you can rotate your object around any vector you want, not just the three axes. For instance, if you stabbed your piece of cheese diagonally from one corner to another, you have created a vector that isn't an axis, but still you can spin the toothpick and rotate the cheese. If you remember the first chapter, I mentioned the rotation method used in JSR 184. It looks something like this:
nameOfRotation(float degrees, float x, float y, float z)
The three floats, x, y and z, are the components of the vector you wish to rotate around. Now, to rotate around a single axis you just supply the x-axis vector. The x-axis vector is (quite logically) 1.0, 0.0, 0.0. That is, a positive one on the x-axis and zeros on the other axes.
There are some problems with 3D rotation, though. Namely, the rotation is order-sensitive. Rotating an object around the x-axis, then the y-axis and then the z-axis is completely different from doing it in any other sequence. Also, if you have rotated an object around one axis, you also rotate its other axes. This creates another problem, where the x-axis actually moves if you rotate around the y-axis first, and thus a rotation around the x-axis won't give the desired effect. Usually a simple 3D game doesn't have to worry about this, as one usually doesn't rotate most models around all axes, and even if you do, you can usually store the degree of rotation on each axis and use the setRotation method instead. I won't go into depth about Orientation of an object and its axes here, instead that'll be saved for one of the advanced tutorials later on. Don't let this trouble your mind right now.
Another thing that I'll mention about rotation is local rotation and world rotation. There's a difference if you rotate an object in its own local coordinate system or if you rotate it after it has been translated to world coordinates. The difference is that rotation in its local coordinate system occurs around its local coordinate axes, and in the world coordinate system, it will be rotated along the world's axes.
The 3D Universe
The 3D concept is a bit harder to wrap your head around than
2D. We can all relate to 2D graphics where you have an array of pixels,
which you just dump onto the screen. However, the 3D models and universe
in a 3D game aren't described as "physically" as a 2D PNG image.
Instead all models are mathematically described with points (vertrices)
in a 3D coordinate system. These vertrices, are translated and rotated
(transformed) to their new position with all the translations and
rotations you apply to the model, and lastly in the graphics pipeline,
pixels are plotted from the areas defined by the points. Confused yet? I
won't go into projection formulas, or anything that algebra-heavy, but I
think you should at least know that your models aren't "real" or
"visible" until the last phase of the rendering, where the areas
(polygons) defined by the points (vertrices) get plotted onto a plane
(the screen).
To help you visualize a 3D projection, you can look at the image to the right. This image is a very simplified image of a projection, but it's enough to give you an image in your head. As you see, the "lines" drawn from the polygons into the eye, are the projection lines. The projection can actually be seen as a bullet, shot from a point in the model, straight into the eye of the observer. The bullet, on its way to the eye, passes a leaden plate (the screen) and sticks to it, leaving a dent (pixel). Also, if a bullet shot from Polygon 2 has to pass through Polygon 1, it will never make it to the screen, since Polygon 2 is deeper into the scene. Of course, the projection process is far more complex than this, but this simplified model will do for now. Coding |
Projection of two polygons onto the screen. |
/** Loads our world */
private void loadWorld()
{
try
{
// Loading the world is very simple. Note that I like to use a
// res-folder that I keep all files in. If you normally just put your
// resources in the project root, then load it from the root.
Object3D[] buffer = Loader.load("/res/cube.m3g");
// Find the world node, best to do it the "safe" way
for(int i = 0; i < buffer.length; i++)
{
if(buffer[i] instanceof World)
{
world = (World)buffer[i];
break;
}
}
// Clean objects
buffer = null;
// Now find the cube so we can rotate it
// We know the cube's ID is 1
cube = (Mesh)world.find(13);
}
catch(Exception e)
{
// ERROR!
System.out.println("Loading error!");
reportException(e);
}
}
The abstract class Transformable represents an object in 3D space that can be transformed in some way (scaled, rotated or translated). Many objects inherit from this class. A rule of thumb is that any object that can move in the 3D universe is a subclass of Transformable. If you want detailed information on the Transformable class, please refer to the JSR 184 API documentation. It has many useful methods which we will explore in detail in other parts of this tutorial. For now we will only use one method, the preRotate method. It is a method that simply rotates the object before any translations are applied and thus rotates it around its own local axes. (Remember what I said about that earlier in this tutorial.).
// Check controls
if(key[LEFT])
{
cube.preRotate(5.0f, 0.0f, 0.0f, 1.0f);
}
else if(key[RIGHT])
{
cube.preRotate(-5.0f, 0.0f, 0.0f, 1.0f);
}
else if(key[UP])
{
cube.preRotate(5.0f, 1.0f, 0.0f, 0.0f);
}
else if(key[DOWN])
{
cube.preRotate(-5.0f, 1.0f, 0.0f, 0.0f);
}
if(key[FIRE])
M3GMidlet.die();
}
- Redikod_3D_tutorial_part_2_source_code.zip (6.7 KB)
- 下载次数: 2
发表评论
-
对Java的I/O流理解
2011-02-19 23:04 1961这是很久前另一个BLOG上的,现在不用了。转过来吧,方便查看. ... -
A*寻路(J2ME实现)
2011-02-19 23:00 1283这是很久前另一个BLOG上的,现在不用了。转过来吧,方便查看. ... -
J2ME上检测是否支持特定的API
2011-02-19 22:59 1514这是很久前另一个BLOG上的,现在不用了。转过来吧,方便查看. ... -
J2me paint[转]
2011-02-19 22:58 1428这是很久前另一个BLOG上的,现在不用了。转过来吧,方便查看. ... -
[JSR-184][3D编程指南(译文)]第一部分:快速进入移动JAVA 3D编程世界
2011-01-23 00:37 1706[英文原文&源码下载] ... -
[JSR-184][3D编程指南]Part V: Heightmap terrain rendering using M3G
2011-01-22 23:13 1879<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]Part IV:M3G built-in collision,light physics and camera perspec
2011-01-22 23:04 2123<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]Part III: Particle systems and immediate mode rendering (2)
2011-01-22 22:56 1533<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]Part III: Particle systems and immediate mode rendering (1)
2011-01-22 22:48 2219<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]Part I: Quick jump into the world of Mobile Java 3D programming
2011-01-22 22:07 2314<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]目录索引
2011-01-22 21:25 1413Series of 3D programming tutori ... -
[Kuix][转]Kuix的事件处理机制
2009-10-08 18:19 1652原文连接 kuix这 ... -
[积累]getResourceAsStream()返回null的问题
2009-03-13 22:04 2648getResourceAsStream()可以获取JAR包内的 ... -
[资料]根据J2ME(MIDP)虚拟机对程序编写的优化方式
2009-02-27 09:39 14401、关于虚拟机 我认为 ... -
[资料]MIDP2.0中如何通过代码画半透明的圆和椭圆
2009-02-27 09:10 1601最近在做一个小Demo时,需要画一个半透明的圆,看遍M ... -
[资料]MIDP设计模式之集结贴[JavaME]
2009-02-23 22:07 13831: 架构性宣言: MI ... -
[资料]MVC在J2ME项目中的应用之MVC慨述
2009-02-23 21:48 1268内容提要: 本文简要的介绍了MVC模式的思想,并分析了M ... -
[资料]基于MVC模式的J2ME应用程序框架设计
2009-02-23 21:24 2849原文:http://www.mcu123.com/ ... -
[资料]线程在J2ME应用中的使用
2009-02-22 17:05 1595简要说明: 非常好的一篇文章,谈论到了线程各个方面的问题 ... -
[JSR-135][资料]渐进式下载
2009-02-22 16:17 1893Progressive download ...
相关推荐
总之,【JSR-184】【3D编程指南】Part IV探讨了移动3D图形中的关键元素,包括碰撞检测、光照物理和相机视角控制,这些是创建生动、交互性3D应用的基础。通过学习和实践,开发者可以利用JSR-184在移动设备上创建...
【JSR-184】是Java Micro Edition (Java ME)平台中的一项规范,全称为“Mobile 3D Graphics API”。这个规范旨在为移动设备提供3D图形编程接口,使得开发者能够在小型设备上构建丰富的三维应用程序,如游戏、虚拟...
【JSR-184】是Java Micro Edition (Java ME) 中的一个标准,全称为"Mobile 3D Graphics API",旨在为移动设备提供3D图形编程接口。这个标准允许开发者在小型设备上创建复杂的3D图形应用,比如游戏或者可视化工具。本...
总之,【JSR-184】的3D编程指南Part V专注于使用M3G在移动设备上实现基于高度图的地形渲染,涉及图像处理、3D网格构建、纹理映射、光照以及移动平台的图形渲染技术。通过实践和理解这些概念,你将能够创建出逼真的3D...
java.lang.ClassNotFoundException: javax.measure.converter.ConversionException所需的jar
赠送jar包:undertow-websockets-jsr-2.1.7.Final.jar; 赠送原API文档:undertow-websockets-jsr-2.1.7.Final-javadoc.jar; 赠送源代码:undertow-websockets-jsr-2.1.7.Final-sources.jar; 赠送Maven依赖信息...
**JSR-135编程指导** JSR-135,全称为JavaTM Media Framework API,是Java ME(J2ME)平台中用于多媒体应用开发的重要规范。它为移动和嵌入式设备提供了处理音频、视频和图像的能力,使得开发者能够创建功能丰富的...
赠送jar包:undertow-websockets-jsr-2.1.7.Final.jar; 赠送原API文档:undertow-websockets-jsr-2.1.7.Final-javadoc.jar; 赠送源代码:undertow-websockets-jsr-2.1.7.Final-sources.jar; 赠送Maven依赖信息...
用jsr184编写的手机3d编程实例,用户可以任意旋转箭头,放大缩小等等。包含如何使用数据定义mesh,如何操作camera如何旋转等等,程序功能较繁杂,但是界面较粗糙(数据定义的模型当然是越简单越好啦),学习意义大于...
《3-D Game Development on JSR-184 v1_0_3》是关于使用Java 3D技术在J2ME平台上开发3D游戏的一份重要资料,它为初学者提供了一个宝贵的入门教程。JSR-184,全称为Java ME 3D API,是Java Micro Edition(J2ME)平台...
标题:WebBeans -- JSR-299 描述:WebBeans是Gavin King的力作,专注于为Java EE平台提供上下文与依赖注入(Contexts and Dependency Injection)。 ### WebBeans (JSR-299) 知识点详解 #### 一、架构与合同 Web...
赠送jar包:undertow-websockets-jsr-2.2.14.Final.jar; 赠送原API文档:undertow-websockets-jsr-2.2.14.Final-javadoc.jar; 赠送源代码:undertow-websockets-jsr-2.2.14.Final-sources.jar; 赠送Maven依赖信息...
赠送jar包:jackson-datatype-jsr310-2.12.5.jar; 赠送原API文档:jackson-datatype-jsr310-2.12.5-javadoc.jar; 赠送源代码:jackson-datatype-jsr310-2.12.5-sources.jar; 赠送Maven依赖信息文件:jackson-...
赠送jar包:undertow-websockets-jsr-2.2.14.Final.jar; 赠送原API文档:undertow-websockets-jsr-2.2.14.Final-javadoc.jar; 赠送源代码:undertow-websockets-jsr-2.2.14.Final-sources.jar; 赠送Maven依赖信息...
在实际开发中,我们通常会将这两个库添加到项目的类路径中,然后通过配置和编程API来启用和使用JSR-303验证。例如,在Spring框架中,可以通过在配置文件中启用注解驱动的验证,或者在代码中创建Validator实例并调用...
赠送jar包:jsr311-api-1.1.1.jar; 赠送原API文档:jsr311-api-1.1.1-javadoc.jar; 赠送源代码:jsr311-api-1.1.1-sources.jar; 赠送Maven依赖信息文件:jsr311-api-1.1.1.pom; 包含翻译后的API文档:jsr311-api...
赠送jar包:jackson-datatype-jsr310-2.11.4.jar; 赠送原API文档:jackson-datatype-jsr310-2.11.4-javadoc.jar; 赠送源代码:jackson-datatype-jsr310-2.11.4-sources.jar; 赠送Maven依赖信息文件:jackson-...
JSR-000343则是对这个标准的第2.0版本的规范定义,它详细描述了如何在Java应用程序之间可靠地发送和接收消息。Javadoc是一种特殊的文档生成工具,它能从源代码中的注释生成文档,为开发者提供API的详细说明。 在...
jackson-datatype-jsr310-2.9.8.jar