📄 compliments of redikod 3d programming tutorial for mobile devices using m3g (jsr 184).htm
字号:
<DIV>Now, I've created a simple M3G file, called map. M3G and
I want to render it. To load this file we'll use the Loader.
load method, however as you've just seen it returns an array
of Object3D. We can't use the Object3D array for rendering as
it is so we need to convert it to something that we can render
to screen later on. In this tutorial we'll load the World
node. The World node is the top node of the JSR 184 scene
graph. It holds all kinds of information such as camera,
lighting, background and a lot of meshes. I'll go through
scene graphs and JSR 184's implementation of scene graphs in a
later part of this series, for now you just need to know that
the World class can hold a whole scene, and that's exactly
what we want! Check out this method, it loads the World node
from a M3G file.</DIV>
<DIV> </DIV>
<DIV><FONT face="Courier New" color=#228b22>/** Loads our
world */<BR> private void
loadWorld()<BR>
{<BR>
try<BR>
{<BR>
// Loading the world is very simple. Note that I like to use
a<BR>
// res-folder that I keep all files in. If you normally just
put
your<BR>
// resources in the project root, then load it from the
root.<BR>
Object3D[] buffer =
Loader.load("/res/map.M3G");<BR>
<BR>
// Find the world node, best to do it the "safe"
way<BR>
for(int i = 0; i < buffer.length;
i++)<BR>
{<BR>
if(buffer[i] instanceof
World)<BR>
{<BR>
world =
(World)buffer[i];<BR>
break;<BR>
}<BR>
}<BR>
<BR>
// Clean
objects<BR>
buffer = null;<BR>
}<BR>
catch(Exception
e)<BR>
{<BR>
//
ERROR!<BR>
System.out.println("Loading
error!");<BR>
reportException(e);<BR>
}<BR> }</FONT><BR></DIV>
<DIV> </DIV>
<DIV>As you can see, after we load the Object3D array with the
Loader class, we just simply go through the entire array and
look for the World note. This is the safest way of finding a
World node. After we find our world node we just break out of
the loop and clean our buffer (not that it's needed, as they'd
automatically get cleared upon leaving the method. Good
practice though.)</DIV>
<DIV> </DIV>
<DIV>OK, now we have loaded our World node, which I've already
told you is the top node of a scene graph and holds all scene
information. Before I show you how easy it is to render, let's
first extract a camera so that we can move around the world we
just loaded. </DIV>
<DIV> </DIV>
<DIV><STRONG>Camera handling<BR></STRONG>We have our World
node ready for rendering and now all we need is a camera, that
we can move around in the world. If you remember, I've already
told you that the World node holds Camera information, so we
should be able to extract the camera from the World and
manipulate it.</DIV>
<DIV> </DIV>
<DIV>A camera in JSR 184 is described by the Camera class.
This class makes it very easy to manipulate the camera in our
3D application with simple translation and orientation
methods. The only two methods we'll be using in this example
are the translate(float, float, float) and the
setOrientation(float, float, float, float). The first one
simply moves the camera in 3D space by an offset in x, y and
z. So, for instance, if you wanted to move the camera 3 units
on the X axis and 3 units on the Z axis, you'd do this:</DIV>
<DIV> </DIV>
<DIV><FONT face="Courier New" color=#228b22>Camera cam = new
Camera(); // This is our camera</FONT></DIV>
<DIV><FONT face="Courier New" color=#228b22>//Move
camera X Y Z<BR>cam.translate(3.0f,
0.0f, 3.0f);</FONT></DIV>
<DIV> </DIV>
<DIV>Piece of cake! Each method call translates the camera
further, so two of the above calls would actually translate
the camera 6 units along the x axis and 6 units along the z
axis. Rotating is just as easy, but I have to explain the
method first. It works like almost all 3D API rotation
methods. You have four parameters, the first one is the actual
rotation in degrees and the last three compose an orientation
vector (xAxis, yAxis, zAxis) to rotate around. Orientation and
orientation vectors will come later in the series, for now,
just know this:</DIV>
<DIV> </DIV>
<DIV><FONT face="Courier New" color=#228b22>//Rotate camera 30
degrees around the X axis<BR>cam.setOrientation(30.0f, 1.0f,
0.0f, 0.0f);</FONT></DIV>
<DIV><FONT face="Courier New" color=#228b22>//Rotate camera 30
degrees around the Y axis<BR>cam.setOrientation(30.0f, 0.0f,
1.0f, 0.0f);</FONT></DIV>
<DIV><FONT face="Courier New" color=#228b22>//Rotate camera 30
degrees around the Z axis<BR>cam.setOrientation(30.0f, 0.0f,
0.0f, 1.0f);</FONT></DIV>
<DIV> </DIV>
<DIV>Note that the method is named setOrientation, which means
that it actually clears any previous rotation you might have
done. I'll assume that you already know what rotation around
an axis means and won't go into detail on that topic
here.</DIV>
<DIV> </DIV>
<DIV>Now that you know everything to make the camera move and
rotate as you wish I'll show you how to extract a Camera from
a World.</DIV>
<DIV> </DIV>
<DIV><FONT face="Courier New" color=#228b22>/** Loads our
camera */<BR> private void
loadCamera()<BR>
{<BR> //
BAD!<BR> if(world ==
null)<BR>
return;<BR>
<BR> // Get the
active camera from the
world<BR> cam =
world.getActiveCamera();<BR>
<BR> // Create a
light<BR> Light l =
new Light();<BR>
<BR> // Make sure
it's AMBIENT<BR>
l.setMode(Light.AMBIENT);<BR>
<BR> // We want a
little higher
intensity<BR>
l.setIntensity(3.0f);<BR>
<BR> // Add it to
our world<BR>
world.addChild(l);<BR> }</FONT></DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>It's that simple? Yes, it's that simple. We just extract
the active camera from the World by using the getActiveCamera.
This gives us the camera that the world was exported with.
With the method above we have a camera that we can move around
as much as we want to. However, the method is doing something
else as well, it adds a light! We will delve deeper into
lights in later parts, but here you see how easy it is to add
a light to your world. I create an Ambient light (for you who
don't know, an ambient light lights all surfaces from all
directions) and add it to the world. This way we get a
very-well lit world. As I told you earlier, the World node can
hold all kinds of information, including light, so we only
need to add the light once to our world and JSR 184 will do
the rest for us. Isn't that handy? Before we get to the last
part; rendering, let's make the camera move. I've already told
you that the array of booleans, key, holds our key information
so all we have to do is query the array and make our camera
behave. First of all, we'll need some variables to make our
camera obey.</DIV>
<DIV> </DIV>
<DIV><FONT face="Courier New" color=#228b22>// Camera
rotation<BR>float camRot = 0.0f;<BR>double camSine =
0.0f;<BR>double camCosine = 0.0f;<BR> <BR>//
Head bobbing<BR>float headDeg = 0.0f;</FONT><BR></DIV>
<DIV> </DIV>
<DIV>The variables above will help us keep track of the
camera's rotation, trigonometry and the head bobbing. The
trigonometry is used for movement later on. Head bobbing is
really quite simple, it's just a cheap effect we'll insert to
make the camera bob up and down as we walk around the world,
for a more natural feeling. All right, all we need to do is
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -