我的java3d学习(二)——载入模型的移动
上一篇给场景载入人物模型。那么如何让他在场景中移动起来呢?我们通过Transform3D类来修改对象在场景中的位置,通过监听键盘按键来改变对象的坐标。源代码如下:
main类
1
package
com.zzl.j3d.viewer;
2
3 import com.sun.j3d.utils.applet.MainFrame;
4 import com.zzl.j3d.loader.KeyInputHandler;
5
6 public class test {
7
8 public static void main(String[] args) {
9
10 Render render = new Render();
11 KeyInputHandler kih = new KeyInputHandler(render);
12
13 new MainFrame(render, 400 , 600 );
14 }
15
16 }
2
3 import com.sun.j3d.utils.applet.MainFrame;
4 import com.zzl.j3d.loader.KeyInputHandler;
5
6 public class test {
7
8 public static void main(String[] args) {
9
10 Render render = new Render();
11 KeyInputHandler kih = new KeyInputHandler(render);
12
13 new MainFrame(render, 400 , 600 );
14 }
15
16 }
场景渲染类:
1
package
com.zzl.j3d.viewer;
2
3 import java.applet.Applet;
4 import java.awt.BorderLayout;
5 import java.awt.GraphicsConfiguration;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.KeyEvent;
8 import java.net.URL;
9 import java.util.Arrays;
10
11 import javax.media.j3d.Appearance;
12 import javax.media.j3d.BoundingSphere;
13 import javax.media.j3d.BranchGroup;
14 import javax.media.j3d.Canvas3D;
15 import javax.media.j3d.Group;
16 import javax.media.j3d.Texture;
17 import javax.media.j3d.TextureAttributes;
18 import javax.media.j3d.Transform3D;
19 import javax.media.j3d.TransformGroup;
20 import javax.swing.Timer;
21 import javax.vecmath.Point3d;
22 import javax.vecmath.Quat4f;
23 import javax.vecmath.Vector3d;
24 import javax.vecmath.Vector3f;
25
26 import com.sun.j3d.loaders.Scene;
27 import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
28 import com.sun.j3d.utils.geometry.Box;
29 import com.sun.j3d.utils.geometry.Primitive;
30 import com.sun.j3d.utils.image.TextureLoader;
31 import com.sun.j3d.utils.universe.SimpleUniverse;
32 import com.sun.j3d.utils.universe.ViewingPlatform;
33 import com.zzl.j3d.loader.J3DLoader;
34 import com.zzl.j3d.loader.KeyInputHandler;
35
36 public class Render extends Applet {
37 private final float PI_180 = ( float ) (Math.PI / 180.0 );
38
39 private SimpleUniverse universe ;
40 private Canvas3D canvas;
41 private BoundingSphere bounds = new BoundingSphere( new Point3d( 0.0 , 0.0 , 0.0 ), 1000.0 );
42 private Transform3D tans = new Transform3D();
43 private TransformGroup objTransG = null ;
44 private Timer timer = null ;
45
46 private float walkbias = 0 ;
47 private float walkbiasangle = 0 ;
48 private float heading;
49
50 private float xloc = 0f;
51 private float yloc = 0f;
52 private float zloc = 0f;
53
54 private float yrot; // Y Rotation
55
56 /**
57 * 创建场景
58 */
59 public Render()
60 {
61 setLayout( new BorderLayout());
62 GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
63 canvas = new Canvas3D(gc);
64 add( " Center " ,canvas);
65
66 universe = new SimpleUniverse(canvas);
67
68 setupView();
69
70 J3DLoader loader = new J3DLoader();
71 BranchGroup objRoot = new BranchGroup();
72
73 URL texImage = loader.loadTexture( " resource/flooring.jpg " );
74 Group group = this .createSceneBackGround(texImage);
75
76 objTransG = new TransformGroup();
77 objTransG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
78 Transform3D pos0 = new Transform3D();
79 pos0.setTranslation( new Vector3f(0f, - 1.1f ,0f));
80 objTransG.setTransform(pos0);
81 objTransG.addChild(group);
82 objRoot.addChild(objTransG);
83
84 // 载入人物模型
85 Scene scene = loader.loadObj( " Liit.obj " );
86
87 Transform3D pos1 = new Transform3D();
88 pos1.setTranslation( new Vector3f(0f, 0.0f ,0f));
89 // 该 人物模型载入时默认为平行y=0平面,所以要绕x轴旋转90度
90 pos1.rotX(Math.toRadians( - 90 ));
91
92 objTransG = new TransformGroup();
93
94 objTransG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
95 objTransG.setTransform(pos1);
96
97 objTransG.addChild(scene.getSceneGroup());
98
99 objRoot.addChild(objTransG);
100
101 universe.addBranchGraph(objRoot);
102 }
103
104 /**
105 * 建立鼠标控制的视点
106 */
107 public void setupView()
108 {
109 /** Add some view related things to view branch side of scene graph */
110 // add mouse interaction to the ViewingPlatform
111 OrbitBehavior orbit = new OrbitBehavior(canvas, OrbitBehavior.REVERSE_ALL | OrbitBehavior.STOP_ZOOM);
112 orbit.setSchedulingBounds(bounds);
113 ViewingPlatform viewingPlatform = universe.getViewingPlatform();
114 // This will move the ViewPlatform back a bit so the
115 // objects in the scene can be viewed.
116 viewingPlatform.setNominalViewingTransform();
117 viewingPlatform.setViewPlatformBehavior(orbit);
118 }
119
120 public void init()
121 {
122 }
123
124 public void destroy()
125 {
126 universe.removeAllLocales();
127 }
128
129 /**
130 * 绘制一个地板
131 * @param texImage
132 * @return
133 */
134 public Group createSceneBackGround(URL texImage)
135 {
136 return createGeometry(Texture.MULTI_LEVEL_POINT , - 0.0f , texImage);
137 }
138
139 public Group createGeometry( int filter, float y, URL texImage)
140 {
141 Group topNode = new Group();
142 Appearance appearance = new Appearance();
143 TextureLoader tex = new TextureLoader(texImage, TextureLoader.GENERATE_MIPMAP , this );
144 Texture texture = tex.getTexture();
145
146 texture.setMinFilter(filter);
147 appearance.setTexture(texture);
148 TextureAttributes texAttr = new TextureAttributes();
149 texAttr.setTextureMode(TextureAttributes.MODULATE);
150 appearance.setTextureAttributes(texAttr);
151
152 Transform3D pos2 = new Transform3D();
153 pos2.setTranslation( new Vector3f(0f,y,0f));
154 objTransG = new TransformGroup();
155 objTransG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
156 objTransG.setTransform(pos2);
157
158
159 Box box = new Box(6f, 0.1f ,8f,Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,appearance);
160 objTransG.addChild(box);
161 topNode.addChild(objTransG);
162 return topNode;
163 }
164
165 /**
166 * 键盘被按下时调用
167 */
168 public void processKeyEvent(KeyEvent e)
169 {
170 if ( ! timer.isRunning())
171 timer.start();
172
173 if (e.getKeyChar() == ' w ' )
174 {
175 xloc += ( float ) Math.sin(heading * PI_180) * 0.05f ;
176 zloc += ( float ) Math.cos(heading * PI_180) * 0.05f ;
177 if (walkbiasangle <= 1.0f ) {
178 walkbiasangle = 359.0f ;
179 } else {
180 walkbiasangle -= 10 ;
181 }
182 walkbias = ( float ) Math.sin(walkbiasangle * PI_180) / 20.0f ;
183 }
184 if (e.getKeyChar() == ' s ' )
185 {
186 xloc -= ( float ) Math.sin(heading * PI_180) * 0.05f ;
187 zloc -= ( float ) Math.cos(heading * PI_180) * 0.05f ;
188 if (walkbiasangle >= 359.0f ) {
189 walkbiasangle = 0.0f ;
190 } else {
191 walkbiasangle += 10 ;
192 }
193 walkbias = ( float ) Math.sin(walkbiasangle * PI_180) / 20.0f ;
194 }
195 if (e.getKeyChar() == ' d ' ) {
196 xloc -= 0.05f ;
197 }
198
199 if (e.getKeyChar() == ' a ' ) {
200 xloc += 0.05f ;
201 }
202 }
203
204 public void processAction(ActionEvent e)
205 {
206 if ( ! timer.isRunning())
207 timer.start();
208
209 tans.setRotation( new Quat4f(1f,0f,0f, - 1.0f ));
210 float xtrans = - xloc;
211 float ztrans = - zloc;
212 float ytrans = - walkbias;
213 float sceneroty = 360.0f - yrot;
214
215 tans.setTranslation( new Vector3d(xtrans, ytrans, ztrans));
216 objTransG.setTransform(tans);
217 }
218
219 /**
220 * 添加监听器
221 * @param kih
222 */
223 public void registerAction(KeyInputHandler kih)
224 {
225 canvas.addKeyListener(kih);
226
227 timer = new Timer( 100 ,kih);
228 }
229 }
230
2
3 import java.applet.Applet;
4 import java.awt.BorderLayout;
5 import java.awt.GraphicsConfiguration;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.KeyEvent;
8 import java.net.URL;
9 import java.util.Arrays;
10
11 import javax.media.j3d.Appearance;
12 import javax.media.j3d.BoundingSphere;
13 import javax.media.j3d.BranchGroup;
14 import javax.media.j3d.Canvas3D;
15 import javax.media.j3d.Group;
16 import javax.media.j3d.Texture;
17 import javax.media.j3d.TextureAttributes;
18 import javax.media.j3d.Transform3D;
19 import javax.media.j3d.TransformGroup;
20 import javax.swing.Timer;
21 import javax.vecmath.Point3d;
22 import javax.vecmath.Quat4f;
23 import javax.vecmath.Vector3d;
24 import javax.vecmath.Vector3f;
25
26 import com.sun.j3d.loaders.Scene;
27 import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
28 import com.sun.j3d.utils.geometry.Box;
29 import com.sun.j3d.utils.geometry.Primitive;
30 import com.sun.j3d.utils.image.TextureLoader;
31 import com.sun.j3d.utils.universe.SimpleUniverse;
32 import com.sun.j3d.utils.universe.ViewingPlatform;
33 import com.zzl.j3d.loader.J3DLoader;
34 import com.zzl.j3d.loader.KeyInputHandler;
35
36 public class Render extends Applet {
37 private final float PI_180 = ( float ) (Math.PI / 180.0 );
38
39 private SimpleUniverse universe ;
40 private Canvas3D canvas;
41 private BoundingSphere bounds = new BoundingSphere( new Point3d( 0.0 , 0.0 , 0.0 ), 1000.0 );
42 private Transform3D tans = new Transform3D();
43 private TransformGroup objTransG = null ;
44 private Timer timer = null ;
45
46 private float walkbias = 0 ;
47 private float walkbiasangle = 0 ;
48 private float heading;
49
50 private float xloc = 0f;
51 private float yloc = 0f;
52 private float zloc = 0f;
53
54 private float yrot; // Y Rotation
55
56 /**
57 * 创建场景
58 */
59 public Render()
60 {
61 setLayout( new BorderLayout());
62 GraphicsConfiguration gc = SimpleUniverse.getPreferredConfiguration();
63 canvas = new Canvas3D(gc);
64 add( " Center " ,canvas);
65
66 universe = new SimpleUniverse(canvas);
67
68 setupView();
69
70 J3DLoader loader = new J3DLoader();
71 BranchGroup objRoot = new BranchGroup();
72
73 URL texImage = loader.loadTexture( " resource/flooring.jpg " );
74 Group group = this .createSceneBackGround(texImage);
75
76 objTransG = new TransformGroup();
77 objTransG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
78 Transform3D pos0 = new Transform3D();
79 pos0.setTranslation( new Vector3f(0f, - 1.1f ,0f));
80 objTransG.setTransform(pos0);
81 objTransG.addChild(group);
82 objRoot.addChild(objTransG);
83
84 // 载入人物模型
85 Scene scene = loader.loadObj( " Liit.obj " );
86
87 Transform3D pos1 = new Transform3D();
88 pos1.setTranslation( new Vector3f(0f, 0.0f ,0f));
89 // 该 人物模型载入时默认为平行y=0平面,所以要绕x轴旋转90度
90 pos1.rotX(Math.toRadians( - 90 ));
91
92 objTransG = new TransformGroup();
93
94 objTransG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
95 objTransG.setTransform(pos1);
96
97 objTransG.addChild(scene.getSceneGroup());
98
99 objRoot.addChild(objTransG);
100
101 universe.addBranchGraph(objRoot);
102 }
103
104 /**
105 * 建立鼠标控制的视点
106 */
107 public void setupView()
108 {
109 /** Add some view related things to view branch side of scene graph */
110 // add mouse interaction to the ViewingPlatform
111 OrbitBehavior orbit = new OrbitBehavior(canvas, OrbitBehavior.REVERSE_ALL | OrbitBehavior.STOP_ZOOM);
112 orbit.setSchedulingBounds(bounds);
113 ViewingPlatform viewingPlatform = universe.getViewingPlatform();
114 // This will move the ViewPlatform back a bit so the
115 // objects in the scene can be viewed.
116 viewingPlatform.setNominalViewingTransform();
117 viewingPlatform.setViewPlatformBehavior(orbit);
118 }
119
120 public void init()
121 {
122 }
123
124 public void destroy()
125 {
126 universe.removeAllLocales();
127 }
128
129 /**
130 * 绘制一个地板
131 * @param texImage
132 * @return
133 */
134 public Group createSceneBackGround(URL texImage)
135 {
136 return createGeometry(Texture.MULTI_LEVEL_POINT , - 0.0f , texImage);
137 }
138
139 public Group createGeometry( int filter, float y, URL texImage)
140 {
141 Group topNode = new Group();
142 Appearance appearance = new Appearance();
143 TextureLoader tex = new TextureLoader(texImage, TextureLoader.GENERATE_MIPMAP , this );
144 Texture texture = tex.getTexture();
145
146 texture.setMinFilter(filter);
147 appearance.setTexture(texture);
148 TextureAttributes texAttr = new TextureAttributes();
149 texAttr.setTextureMode(TextureAttributes.MODULATE);
150 appearance.setTextureAttributes(texAttr);
151
152 Transform3D pos2 = new Transform3D();
153 pos2.setTranslation( new Vector3f(0f,y,0f));
154 objTransG = new TransformGroup();
155 objTransG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
156 objTransG.setTransform(pos2);
157
158
159 Box box = new Box(6f, 0.1f ,8f,Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,appearance);
160 objTransG.addChild(box);
161 topNode.addChild(objTransG);
162 return topNode;
163 }
164
165 /**
166 * 键盘被按下时调用
167 */
168 public void processKeyEvent(KeyEvent e)
169 {
170 if ( ! timer.isRunning())
171 timer.start();
172
173 if (e.getKeyChar() == ' w ' )
174 {
175 xloc += ( float ) Math.sin(heading * PI_180) * 0.05f ;
176 zloc += ( float ) Math.cos(heading * PI_180) * 0.05f ;
177 if (walkbiasangle <= 1.0f ) {
178 walkbiasangle = 359.0f ;
179 } else {
180 walkbiasangle -= 10 ;
181 }
182 walkbias = ( float ) Math.sin(walkbiasangle * PI_180) / 20.0f ;
183 }
184 if (e.getKeyChar() == ' s ' )
185 {
186 xloc -= ( float ) Math.sin(heading * PI_180) * 0.05f ;
187 zloc -= ( float ) Math.cos(heading * PI_180) * 0.05f ;
188 if (walkbiasangle >= 359.0f ) {
189 walkbiasangle = 0.0f ;
190 } else {
191 walkbiasangle += 10 ;
192 }
193 walkbias = ( float ) Math.sin(walkbiasangle * PI_180) / 20.0f ;
194 }
195 if (e.getKeyChar() == ' d ' ) {
196 xloc -= 0.05f ;
197 }
198
199 if (e.getKeyChar() == ' a ' ) {
200 xloc += 0.05f ;
201 }
202 }
203
204 public void processAction(ActionEvent e)
205 {
206 if ( ! timer.isRunning())
207 timer.start();
208
209 tans.setRotation( new Quat4f(1f,0f,0f, - 1.0f ));
210 float xtrans = - xloc;
211 float ztrans = - zloc;
212 float ytrans = - walkbias;
213 float sceneroty = 360.0f - yrot;
214
215 tans.setTranslation( new Vector3d(xtrans, ytrans, ztrans));
216 objTransG.setTransform(tans);
217 }
218
219 /**
220 * 添加监听器
221 * @param kih
222 */
223 public void registerAction(KeyInputHandler kih)
224 {
225 canvas.addKeyListener(kih);
226
227 timer = new Timer( 100 ,kih);
228 }
229 }
230
键盘监听类:
1
/**
2 * 键盘处理类
3 */
4 package com.zzl.j3d.loader;
5
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.awt.event.KeyAdapter;
9 import java.awt.event.KeyEvent;
10
11 import com.zzl.j3d.viewer.Render;
12
13 public class KeyInputHandler extends KeyAdapter implements ActionListener{
14 private Render render;
15
16 /**
17 * 键盘处理类。注册键盘监听器
18 * @param render
19 */
20 public KeyInputHandler(Render render)
21 {
22 this .render = render;
23 render.registerAction( this );
24 }
25
26 /**
27 * 按键被按下时调用
28 * @param e
29 */
30 public void keyPressed(KeyEvent e)
31 {
32 processKeyEvent(e, true );
33 }
34 /**
35 * 按键被放开时调用
36 * @param e
37 */
38 public void keyReleased(KeyEvent e)
39 {
40
41 }
42 /**
43 * 按一个键时调用
44 * @param e
45 */
46 public void keyTyped(KeyEvent e)
47 {
48
49 }
50
51 @Override
52 public void actionPerformed(ActionEvent e) {
53 render.processAction(e);
54 }
55
56 /**
57 * 键盘被按下时处理的事件
58 * @param e
59 * @param pressed
60 */
61 private void processKeyEvent(KeyEvent e, boolean pressed)
62 {
63 render.processKeyEvent(e);
64 }
65 }
2 * 键盘处理类
3 */
4 package com.zzl.j3d.loader;
5
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.awt.event.KeyAdapter;
9 import java.awt.event.KeyEvent;
10
11 import com.zzl.j3d.viewer.Render;
12
13 public class KeyInputHandler extends KeyAdapter implements ActionListener{
14 private Render render;
15
16 /**
17 * 键盘处理类。注册键盘监听器
18 * @param render
19 */
20 public KeyInputHandler(Render render)
21 {
22 this .render = render;
23 render.registerAction( this );
24 }
25
26 /**
27 * 按键被按下时调用
28 * @param e
29 */
30 public void keyPressed(KeyEvent e)
31 {
32 processKeyEvent(e, true );
33 }
34 /**
35 * 按键被放开时调用
36 * @param e
37 */
38 public void keyReleased(KeyEvent e)
39 {
40
41 }
42 /**
43 * 按一个键时调用
44 * @param e
45 */
46 public void keyTyped(KeyEvent e)
47 {
48
49 }
50
51 @Override
52 public void actionPerformed(ActionEvent e) {
53 render.processAction(e);
54 }
55
56 /**
57 * 键盘被按下时处理的事件
58 * @param e
59 * @param pressed
60 */
61 private void processKeyEvent(KeyEvent e, boolean pressed)
62 {
63 render.processKeyEvent(e);
64 }
65 }
模型载入类:
1
package
com.zzl.j3d.loader;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7
8 import com.sun.j3d.loaders.IncorrectFormatException;
9 import com.sun.j3d.loaders.ParsingErrorException;
10 import com.sun.j3d.loaders.Scene;
11 import com.sun.j3d.loaders.objectfile.ObjectFile;
12
13 public class J3DLoader {
14
15 private static java.net.URL texImage = null ;
16
17 /**
18 * 载入obj模型
19 * @param arg0 String 模型文件名
20 * @return Scene
21 */
22 public Scene loadObj(String arg0)
23 {
24 int flags = ObjectFile.RESIZE;
25 ObjectFile f = new ObjectFile(flags,( float )( 49.0 * Math.PI / 180.0 ));
26 // 创建场景叶节点
27 Scene s = null ;
28 try {
29 s = f.load(arg0);
30 } catch (FileNotFoundException e) {
31 // TODO Auto-generated catch block
32 e.printStackTrace();
33 } catch (IncorrectFormatException e) {
34 // TODO Auto-generated catch block
35 e.printStackTrace();
36 } catch (ParsingErrorException e) {
37 // TODO Auto-generated catch block
38 e.printStackTrace();
39 }
40 return s;
41 }
42
43 /**
44 * 载入纹理图片
45 * @param args String 图片文件名
46 * @return URL
47 */
48 public URL loadTexture(String args)
49 {
50 File f = new File(args);
51 try {
52 texImage = f.toURL();
53 } catch (MalformedURLException e) {
54 // TODO Auto-generated catch block
55 e.printStackTrace();
56 }
57 return texImage;
58 }
59 }
60
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7
8 import com.sun.j3d.loaders.IncorrectFormatException;
9 import com.sun.j3d.loaders.ParsingErrorException;
10 import com.sun.j3d.loaders.Scene;
11 import com.sun.j3d.loaders.objectfile.ObjectFile;
12
13 public class J3DLoader {
14
15 private static java.net.URL texImage = null ;
16
17 /**
18 * 载入obj模型
19 * @param arg0 String 模型文件名
20 * @return Scene
21 */
22 public Scene loadObj(String arg0)
23 {
24 int flags = ObjectFile.RESIZE;
25 ObjectFile f = new ObjectFile(flags,( float )( 49.0 * Math.PI / 180.0 ));
26 // 创建场景叶节点
27 Scene s = null ;
28 try {
29 s = f.load(arg0);
30 } catch (FileNotFoundException e) {
31 // TODO Auto-generated catch block
32 e.printStackTrace();
33 } catch (IncorrectFormatException e) {
34 // TODO Auto-generated catch block
35 e.printStackTrace();
36 } catch (ParsingErrorException e) {
37 // TODO Auto-generated catch block
38 e.printStackTrace();
39 }
40 return s;
41 }
42
43 /**
44 * 载入纹理图片
45 * @param args String 图片文件名
46 * @return URL
47 */
48 public URL loadTexture(String args)
49 {
50 File f = new File(args);
51 try {
52 texImage = f.toURL();
53 } catch (MalformedURLException e) {
54 // TODO Auto-generated catch block
55 e.printStackTrace();
56 }
57 return texImage;
58 }
59 }
60