Home  >  Article  >  Backend Development  >  J2ME Mobile 3D introductory tutorial series article two

J2ME Mobile 3D introductory tutorial series article two

黄舟
黄舟Original
2016-12-19 13:53:041001browse

Here I would like to first thank you all for your support for the previous article, one of the J2ME Mobile 3D introductory tutorial series. It is with your support that I decided to share my Mobile3D learning process with you. I hope you can Let’s discuss Mobile3D.
 
 In the last tutorial, I gave you a detailed introduction to creating 3D graphics through real-time calculations in Moble3D, and gave a brief introduction to importing models from *.m3g files. This time I want to pass it on here. The use of *.m3g files briefly introduces Mobile3D's control of animation and some operations on the model.
 
First of all, let me briefly talk about the creation of m3g files. This is actually very simple. You only need to choose a 3D graphics production software that you are familiar with and install the corresponding plug-in. The software I use here is Maya. and 3DS MAX, the plug-in uses H3T EXPort Plugin, which is available for maya and 3ds max. You also need to download a software M3G Tools kit.
 
 These can be found on the Sony EriCSSon website. There should be no problem installing the plug-in. After the plug-in is installed, you can create the model, set the texture map, set the camera, set the key frame, etc., and finally just export it to an H3T file. Then open M3G Tools kit can output h3t files into m3g files. It is best to use M3G Tools before using m3g files Kit browses the file to record the corresponding information, such as userid and tree structure of the scene, which are very important. If you do this, you will find that the camera in the m3g file exported in this way is not under the world tree, but is at the same level as the world tree.
 
In fact, I also said in the previous article that camera and rendering information do not need to be placed under the world tree, but all model information must be placed under the tree. When we look at the m3g file, it is more important to see clearly the location of the world node and the userid of the model that we need to operate.
  
  The preparatory work is almost done, now let’s look at Mobile3D. In the previous article, I said that m3g files are loaded through javax.microedition.m3g.Loader.load(String url), and this method returns javax. Array of microedition.m3g.Object3D, some people may ask that since world is the root node, why not directly return a World?
 
 When I just showed you the structure of the m3g file, I already explained that the camera and animation settings are not placed in the book with the World node, but are at the same level as the World node. The World node is the root node of the scene. So how do we correctly remove the World node? There are two methods:
 
 1. Traverse the Object3D array and compare the useid of each element. If the useid of the official World node is used, the element will be taken out.
 
 2. Traverse the Object3D array and compare whether each element is an instance of the World class. Since the World node is the root node of the scene, there should be only one instance object of the World class in the Object3D array.
 
 The first method is relatively simple. I only give a fragment of the code of the second method here. (actually the same)
  
 PRivate void loadWorld(){
 System.out.println("now loading...");
 try{
 buffer=Loader.load("/img/TmpMicroFile.m3g");
  for(int i=0;i if(buffer[i] instanceof World){
 world=(World)buffer[i];
  return ;
  }
  }
  }catch(Exception e){
 buffer=null;
 System.out.println("thorw an exception when loading");
 e.printStackTrace();
 }
 }
 
  Then we set the camera. The difference is that this time we get the camera information from World. After obtaining We can make some basic settings, which I won’t go into details here. Let’s focus on the animation part. When we import this m3g file, we actually already have animation information, and this animation information may be It's very complicated. I tested the movement of the two axes of the connecting rod and it works fine. From some information, there is no problem with the IK reverse movement. Maybe you are already worried. Why don't you tell me how to control the animation playback? Simply put, World.animate() updates animation information. This method needs to pass in an int type parameter. When you call this method for the first time, the system will record this value, and it will be compared with every subsequent call. This value is compared, and then the system calculates for us where to update the animation. At the same time, this method will return an int type parameter, which represents a recommended value for the next update (in milliseconds)
.
 At this time, we can let the thread that calls this method sleep for this time so that the animation data can be updated next time. You may have questions here. My animation obviously only has dozens of frames, but it is played repeatedly here; although this is a Good news, but what if we need to control the length and time of playback in many cases?
 
At this time we need to use the javax.microedition.m3g.AnimationController class. In fact, each movable model in each animation has its own AnimationController object. Like the model animation, we can use World.find(int controllerID), in this class we can use setActiveInterval(int activeTime,int unactiveTime) to set the start and focus time of animation playback in the system, and setPosition(int startTime,int endTime) method controls which paragraph of this animation needs to be played.
 
 Sorry that I did not use the two methods in this tutorial example, but if you want to know about the use of these two methods, I suggest you take a look at the kangaroo example in Demo3D of WTK2.2. It's pretty specific in there. Here I give code snippets for animation and drawing. g .setColor(0x00);
 g.fillRect(0,0,getWidth(), getHeight());
 
 g.setClip(0,0,getWidth(),getHeight());
 g3d.bindTarget(g, true,Graphics3D.DITHERGraphics3D.TRUE_COLOR);
 g3d.setViewport(0,0,getWidth(),getHeight());
 
 g3d.render(world);
 
 g3d.releaseTarget();
 
 framePor=(int )1000/((int)System.currentTimeMillis()-perFrameTime);
 
 System.out.println("3D demo frame/sn:"+framePor);
 
 if(validity < 1)
 { // The validity too small; allow a minimum of 1ms.
   validity = 1;
}
b public void run () {
while (isrun) {
repaint ();
try {
thread.sleep (value);
} Catch (Exception E) {}}}

If you if you if you, if you If you don't like using threads, you can switch to Timer. It's a matter of personal preference. I'm familiar with threads, so I use threads here.
 
 It seems that I only understand these animations now, and I share them all with you. Next I want to talk about several methods in the Transformable class. First, let’s introduce the Transformable class. The Transformable class is a very important class, and Node is its subclass. Do you know its importance?
 
 There are four methods in Transformable that I will briefly talk about today: postRotate(float, float, float, float) is related to the rotation of the object. In Mobile3D, the rotation axis of all objects is at its own center by default, so when rotating an object, it must be rotating on its own axis, not around a certain point or axis. Revolution, this must be clarified. Maybe this is a bit abstract, so let me put it another way: the rotation here only changes the orientation of the object, but does not change the position of the object.
  
 Now you understand, maybe someone wants to ask, "Isn't this exactly what we need? Why should we emphasize it?" The reason is actually this. In some 3D engines, rotation is based on the origin. That is to say, if you need to perform rotational motion, you must move, rotate, and move again. In fact, the advantage of doing this is that it can facilitate point calculations, because there is no concept of rotation for points. To some extent, our Mobile3D cannot operate on points, so its smallest unit is Mesh. So how does it achieve rotation? You will understand if you look at a matrix
  
  90, 0, 0, 0
  0, 0, 0, 0
  0, 0, 1, 0
  0, 0, 0, 0
  
  This matrix represents the current model There is a 90 degree rotation on the Y axis. Now let's go back and look at postRotate(float a, float x, float y, float z) method, which has 4 parameters. The first one is the angle that needs to be rotated this time. The last three are actually the axis of this rotation, which is represented by a vector. The postRotate method continues in the original orientation. The new rotation, if expressed by a mathematical formula, is to use the original matrix multiplied by
 
 a,0,0,0
 0,x,0,0
 0,0,y,0
 0,0,0 ,z
 
 This matrix is ​​the new direction matrix. If this method sounds difficult to understand from a mathematical perspective, you only need to remember the four parameters. The first is the angle of this rotation, and the last three determine the axis of rotation.
Similar to the postRotate method is setOrientation(float a, float x, float y, float z). The difference is that this time it is no longer rotated but directly set to this orientation.
 
 After talking about rotation, let’s look at movement. This seems to be much simpler translate(float x, float y, float z) This refers to translation according to the specified vector; setTranslation(float x, float y, float z) This is simpler, move directly to the specified position.
 
In fact, there is another method scale(float sx, float sy, float sz) is used for scaling, as well as setScale(float sx, float sy, float sz) Set the scale directly. These six methods are for direct manipulation of objects and are very useful. Especially the first four are often used when writing games. The latter two seem to be used less frequently because there are many Sometimes we directly operate the distance of the camera (unless there is an extraordinary need). Let me give an example of using the first four methods below.
 
 public void keyPressed(int keycode){
 float[] camerTra;
 float x;
 float z;
 switch(keycode){
 case GameCanvas.DOWN:
 break;
case GameCanvas.UP:
 break;
 case 52:
 dir=dir-2;
 System.out.println(dir);
 2. For more related content, please pay attention to the PHP Chinese website (www.php.cn)

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn