先还是大体说一下这个程序的原理吧(正方体与球体之间)。
(1)建立相关对象:正方体,3个球体以及为它们铺上纹理
(2)分别为每个对象设定碰撞模式,方法为setCollisionMode(int mode),3个球体为COLLISION_CHECK_OTHERS,cube为COLLISION_CHECK_SELF
(3)将其添加到world对象中,及处理必要的Camera参数
(4)在onDrawFrame函数中进行碰撞处理工作,因为是球体与正方体之间的碰撞,所以采用了相近的椭圆碰撞检测checkForCollisionEllipsoid(如果要用球体检测checkForCollisionSpherical,也能很好工作,这在代码处有相应注释)
(1)Activity类
1.
2.package sim.feel;
3.import android.app.Activity;
4.import android.content.res.Resources;
5.import android.graphics.Bitmap;
6.import android.graphics.BitmapFactory;
7.import android.opengl.GLSurfaceView;
8.import android.os.Bundle;
9./**
10. * Activity类
11.*
12. * @author Administrator
13. *
14. */
15.public class Basic_collision extends Activity {
16. private GLSurfaceView glView;
17. private MyRenderer mr = new MyRenderer();
18. // onCreate
19. public void onCreate(Bundle savedInstanceState) {
20. super.onCreate(savedInstanceState);
21. // 传入Resources方法
22. LoadBitmap.loadb(getResources());
23. glView = new GLSurfaceView(this);
24. glView.setRenderer(mr);
25. setContentView(glView);
26. }
27.}
28.// 载入位图文件
29.class LoadBitmap {
30. public static Bitmap bitmap;
31. // 载入位图方法
32.public static void loadb(Resources res) {
33. bitmap = BitmapFactory.decodeResource(res, R.drawable.icon);
34. }
35.}
(2)MyRenderer类
1.
2.package sim.feel;
3.import javax.microedition.khronos.egl.EGLConfig;
4.import javax.microedition.khronos.opengles.GL10;
5.import android.opengl.GLSurfaceView.Renderer;
6.import com.threed.jpct.Camera;
7.import com.threed.jpct.Config;
8.import com.threed.jpct.FrameBuffer;
9.import com.threed.jpct.Logger;
10.import com.threed.jpct.Object3D;
11.import com.threed.jpct.Primitives;
12.import com.threed.jpct.RGBColor;
13.import com.threed.jpct.SimpleVector;
14.import com.threed.jpct.Texture;
15.import com.threed.jpct.TextureManager;
16.import com.threed.jpct.World;
17.import com.threed.jpct.util.MemoryHelper;
18./**
19. * MyRenderer类
20.*
21. * @author Administrator
22. *
23. */
24.public class MyRenderer implements Renderer {
25. // FrameBuffer对象
26.private FrameBuffer fb;
27. // World对象
28.private World world;
29. // RGBColor
30. private RGBColor back = new RGBColor(50, 50, 100);
31. // Object3D对象
32.private Object3D sphere1 = null;
33. private Object3D sphere2 = null;
34. private Object3D sphere3 = null;
35. private Object3D cube = null;
36. // SimpleVector
37. // 通过设置组件的x,y,z向量来创建一个SimpleVector对象
38.private SimpleVector move = new SimpleVector(0, 0.3, 1);
39. // 被碰撞Object3D的x,y,z(此处该对象为球体)
40.private SimpleVector ellips = new SimpleVector(7, 7, 7);
41. private SimpleVector tmp = new SimpleVector();
42. // FPS
43. private int fps = 0;
44. private long time = System.currentTimeMillis();
45. private boolean stop = false;
46. // 默认构造
47.// 对该项目的一些优化
48.public MyRenderer() {
49. // 绘制的最多的Polygon数量,默认为4096,此处如果超过500,则不绘制
50. Config.maxPolysVisible = 500;
51. // 最远的合适的平面,默认为1000
52. Config.farPlane = 1500;
53. // Modifies the multiplicator for the transparency calculations in
54. // jPCT-AE. The actual formula is trans=offset+objTrans*mul, default for
55. // offset is 0.1f.
56. Config.glTransparencyMul = 0.1f;
57. // Modifies the offset for the transparency calculations in jPCT-AE. The
58. // actual formula is trans=offset+objTrans*mul, default for offset is
59. // 0.1f.
60. Config.glTransparencyOffset = 0.1f;
61. // 使JPCT-AE这个引擎使用顶点而不是顶点数组缓冲对象,因为它可能会使某些硬件更快
62. // 但在Samsung Galaxy,它并不能工作的很好,可能使之崩溃,这就是它默认为false的原因
63. Config.useVBO = true;
64. Texture.defaultToMipmapping(true);
65. Texture.defaultTo4bpp(true);
66. }
67. public void onDrawFrame(GL10 gl) {
68. try {
69. if (!stop) {
70. // Do collision detections(碰撞检测)
71. // 第1个参数为cube的移动(translation)
72. // 第2个参数为碰撞的区域大小(ellips)
73. // 此处的第3个参数为:递归深度的碰撞检测,较高的值将提高碰撞检测精度,而且降低性能。合理的值介于1和5。
74. // trsn包含当前的坐标信息
75. SimpleVector trsn = cube.checkForCollisionEllipsoid(move,
76. ellips, 5);
77. // 用下面的球体间碰撞也能很好的工作
78. // SimpleVector trsn = cube.checkForCollisionSpherical(move, 2);
79. // "移动这个对象通过改变其在JPCT-AE坐标系下的矩阵"
80. cube.translate(trsn);
81. // 如果cube当前z轴坐标大于
82. // 100,重置当前cube的旋转值到默认值,换言之,没有了旋转
83. if (cube.getTranslation(tmp).z > 50) {
84. // 清除旋转
85. cube.clearTranslation();
86. // 重置为初始值
87. cube.translate(10, -40, -30);
88. }
89. // 以定义好的RGBColor清屏
90. fb.clear(back);
91. // 变换和灯光所有的多边形
92. world.renderScene(fb);
93. // 绘制由renderScene产生的场景
94. world.draw(fb);
95. // 渲染显示图像
96. fb.display();
97. // fps加1
98. fps++;
99. // 打印输出fps
100. if (System.currentTimeMillis() - time > 1000) {
101. System.out.println(fps + "fps");
102. fps = 0;
103. time = System.currentTimeMillis();
104. }
105. } else {
106. if (fb != null) {
107. fb.dispose();
108. fb = null;
109. }
110. }
111. } catch (Exception e) {
112. e.printStackTrace();
113. // 打印异常信息
114. Logger.log("Drawing thread terminated!", Logger.MESSAGE);
115. }
116. }
117. public void onSurfaceChanged(GL10 gl, int width, int height) {
118. if (fb != null) {
119. fb = null;
120. }
121. // 新产生一个FrameBuffer对象
122. fb = new FrameBuffer(gl, width, height);
123. }
124. public void onSurfaceCreated(GL10 gl, EGLConfig config) {
125. Logger.log("onCreate");
126. // 混合渲染
127. gl.glEnable(GL10.GL_BLEND);
128. gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
129. // 新建world对象
130. world = new World();
131. // 纹理相关
132. TextureManager tm = TextureManager.getInstance();
133. Texture texture2 = new Texture(LoadBitmap.bitmap);
134. tm.addTexture("texture2", texture2);
135. // 初始化各3D元素
136. // 返回一个给定数量的面,第一个20表示面的数量,第二是球体的缩放
137. sphere1 = Primitives.getSphere(20, 20);
138. // 以纹理对象的方式给对象包装上纹理
139. sphere1.calcTextureWrapSpherical();
140. // 为sphere1设置纹理图片
141. sphere1.setTexture("texture2");
142. // 复制当前的Object3D对象
143. sphere2 = sphere1.cloneObject();
144. sphere3 = sphere1.cloneObject();
145. // 返回一个立方体,其中2为其缩放变量
146. cube = Primitives.getCube(2);
147. // 以Z轴20处来旋转球体(其实就是向里移动球体)
148. sphere2.translate(0, 0, 20);
149. // 以Z轴40处来旋转球体
150. sphere3.translate(0, 0, 40);
151. // 以(10, -40, -30)来旋转立方体
152. cube.translate(10, -40, -30);
153. cube.setAdditionalColor(RGBColor.GREEN);
154. // 将3D元素添加到world对象中
155. world.addObject(sphere1);
156. world.addObject(sphere2);
157. world.addObject(sphere3);
158. world.addObject(cube);
159. // 建立碰撞模式
160. sphere1.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
161. world.addObject(sphere1);
162. sphere2.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
163. world.addObject(sphere1);
164. sphere3.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
165. world.addObject(sphere1);
166. // 建立碰撞模式
167. cube.setCollisionMode(Object3D.COLLISION_CHECK_SELF);
168. // 设置环境光
169. world.setAmbientLight(255, 255, 255);
170. // 编译所有对象
171. world.buildAllObjects();
172. // Camera相关
173. Camera cam = world.getCamera();
174. // 向里以50的速度移动
175. cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
176. // 向外以60的速度移动
177. cam.moveCamera(Camera.CAMERA_MOVEUP, 60);
178. // 以sphere2对象作为中心视角
179. cam.lookAt(sphere2.getTransformedCenter());
180. // 回收内存
181. MemoryHelper.compact();
182. }
183.}