libgdx 3D Bullet 碰撞检测二

接上一篇,这里我们使用collisionWorld

直接上代码,细节看注释:

  1 package org.forus.game.test;
  2 
  3 import com.badlogic.gdx.ApplicationListener;
  4 import com.badlogic.gdx.Gdx;
  5 import com.badlogic.gdx.graphics.Color;
  6 import com.badlogic.gdx.graphics.GL20;
  7 import com.badlogic.gdx.graphics.PerspectiveCamera;
  8 import com.badlogic.gdx.graphics.VertexAttributes.Usage;
  9 import com.badlogic.gdx.graphics.g3d.Environment;
 10 import com.badlogic.gdx.graphics.g3d.Material;
 11 import com.badlogic.gdx.graphics.g3d.Model;
 12 import com.badlogic.gdx.graphics.g3d.ModelBatch;
 13 import com.badlogic.gdx.graphics.g3d.ModelInstance;
 14 import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
 15 import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
 16 import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
 17 import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
 18 import com.badlogic.gdx.math.MathUtils;
 19 import com.badlogic.gdx.math.Vector3;
 20 import com.badlogic.gdx.physics.bullet.Bullet;
 21 import com.badlogic.gdx.physics.bullet.collision.ContactListener;
 22 import com.badlogic.gdx.physics.bullet.collision.btBoxShape;
 23 import com.badlogic.gdx.physics.bullet.collision.btBroadphaseInterface;
 24 import com.badlogic.gdx.physics.bullet.collision.btCapsuleShape;
 25 import com.badlogic.gdx.physics.bullet.collision.btCollisionConfiguration;
 26 import com.badlogic.gdx.physics.bullet.collision.btCollisionDispatcher;
 27 import com.badlogic.gdx.physics.bullet.collision.btCollisionObject;
 28 import com.badlogic.gdx.physics.bullet.collision.btCollisionShape;
 29 import com.badlogic.gdx.physics.bullet.collision.btCollisionWorld;
 30 import com.badlogic.gdx.physics.bullet.collision.btConeShape;
 31 import com.badlogic.gdx.physics.bullet.collision.btCylinderShape;
 32 import com.badlogic.gdx.physics.bullet.collision.btDbvtBroadphase;
 33 import com.badlogic.gdx.physics.bullet.collision.btDefaultCollisionConfiguration;
 34 import com.badlogic.gdx.physics.bullet.collision.btDispatcher;
 35 import com.badlogic.gdx.physics.bullet.collision.btSphereShape;
 36 import com.badlogic.gdx.utils.Array;
 37 import com.badlogic.gdx.utils.ArrayMap;
 38 import com.badlogic.gdx.utils.Disposable;
 39 
 40 /**
 41  * Created by HanHongmin on 14-8-23.
 42  */
 43 public class CollisionWorldTest implements ApplicationListener {
 44     final static short GROUND_FLAG = 1<<8;
 45     final static short OBJECT_FLAG = 1<<9;//为什么设置成这样我没细看,可能为了和别的不冲突 http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=5449#p19521
 46     final static short ALL_FLAG = -1;
 47     class MyContactListener extends ContactListener {
 48         @Override
 49         public boolean onContactAdded (int userValue0, int partId0, int index0, int userValue1, int partId1, int index1) {
 50             //此处过滤掉任何两个物体碰撞
 51             //有一个是0,即ground的情况,才把另一个停下来
 52 
 53             //if (userValue1 == 0)
 54                 instances.get(userValue0).moving = false;
 55             //else if (userValue0 == 0)
 56                 instances.get(userValue1).moving = false;
 57 
 58             //如果添加时collisionWorld.addCollisionObject(object.body, GROUND_FLAG, ALL_FLAG)这种带了标记参数,这里不用判断哪个是ground了
 59             return true;
 60         }
 61     }
 62 
 63     static class GameObject extends ModelInstance implements Disposable {
 64         public final btCollisionObject body;
 65         public boolean moving;
 66 
 67         public GameObject (Model model, String node, btCollisionShape shape) {
 68             super(model, node);
 69             body = new btCollisionObject();
 70             body.setCollisionShape(shape);
 71         }
 72 
 73         @Override
 74         public void dispose () {
 75             body.dispose();
 76         }
 77 
 78         static class Constructor implements Disposable {
 79             public final Model model;
 80             public final String node;
 81             public final btCollisionShape shape;
 82 
 83             public Constructor (Model model, String node, btCollisionShape shape) {
 84                 this.model = model;
 85                 this.node = node;
 86                 this.shape = shape;
 87             }
 88 
 89             public GameObject construct () {
 90                 return new GameObject(model, node, shape);
 91             }
 92 
 93             @Override
 94             public void dispose () {
 95                 shape.dispose();
 96             }
 97         }
 98     }
 99 
100     PerspectiveCamera cam;
101     CameraInputController camController;
102     ModelBatch modelBatch;
103     Environment environment;
104     Model model;
105     Array<GameObject> instances;
106     ArrayMap<String, GameObject.Constructor> constructors;
107     float spawnTimer;
108 
109     btCollisionConfiguration collisionConfig;
110     btDispatcher dispatcher;
111     MyContactListener contactListener;
112     btBroadphaseInterface broadphase;
113     btCollisionWorld collisionWorld;
114 
115     @Override
116     public void create () {
117         Bullet.init();
118 
119         modelBatch = new ModelBatch();
120         environment = new Environment();
121         environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
122         environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
123 
124         cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
125         cam.position.set(3f, 7f, 10f);
126         cam.lookAt(0, 4f, 0);
127         cam.near = 1f;
128         cam.far = 300f;
129         cam.update();
130 
131         camController = new CameraInputController(cam);
132         Gdx.input.setInputProcessor(camController);
133 
134         ModelBuilder mb = new ModelBuilder();
135         mb.begin();
136         mb.node().id = "ground";
137         mb.part("ground", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material(ColorAttribute.createDiffuse(Color.RED)))
138                 .box(5f, 1f, 5f);
139         mb.node().id = "sphere";
140         mb.part("sphere", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material(ColorAttribute.createDiffuse(Color.GREEN)))
141                 .sphere(1f, 1f, 1f, 10, 10);
142         mb.node().id = "box";
143         mb.part("box", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material(ColorAttribute.createDiffuse(Color.BLUE)))
144                 .box(1f, 1f, 1f);
145         mb.node().id = "cone";
146         mb.part("cone", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material(ColorAttribute.createDiffuse(Color.YELLOW)))
147                 .cone(1f, 2f, 1f, 10);
148         mb.node().id = "capsule";
149         mb.part("capsule", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material(ColorAttribute.createDiffuse(Color.CYAN)))
150                 .capsule(0.5f, 2f, 10);
151         mb.node().id = "cylinder";
152         mb.part("cylinder", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal,
153                 new Material(ColorAttribute.createDiffuse(Color.MAGENTA))).cylinder(1f, 2f, 1f, 10);
154         model = mb.end();
155 
156         constructors = new ArrayMap<String, GameObject.Constructor>(String.class, GameObject.Constructor.class);
157         constructors.put("ground", new GameObject.Constructor(model, "ground", new btBoxShape(new Vector3(2.5f, 0.5f, 2.5f))));
158         constructors.put("sphere", new GameObject.Constructor(model, "sphere", new btSphereShape(0.5f)));
159         constructors.put("box", new GameObject.Constructor(model, "box", new btBoxShape(new Vector3(0.5f, 0.5f, 0.5f))));
160         constructors.put("cone", new GameObject.Constructor(model, "cone", new btConeShape(0.5f, 2f)));
161         constructors.put("capsule", new GameObject.Constructor(model, "capsule", new btCapsuleShape(.5f, 1f)));
162         constructors.put("cylinder", new GameObject.Constructor(model, "cylinder", new btCylinderShape(new Vector3(.5f, 1f, .5f))));
163 
164         collisionConfig = new btDefaultCollisionConfiguration();
165         dispatcher = new btCollisionDispatcher(collisionConfig);
166         broadphase = new btDbvtBroadphase();
167         collisionWorld = new btCollisionWorld(dispatcher, broadphase, collisionConfig);
168         contactListener = new MyContactListener();
169 
170         instances = new Array<GameObject>();
171         GameObject object = constructors.get("ground").construct();
172         object.body.setUserValue(0);//貌似不设置就是0
173         instances.add(object);
174         collisionWorld.addCollisionObject(object.body, GROUND_FLAG, ALL_FLAG);//同时设置它自身的flag和可以和他碰撞的flag
175     }
176 
177     public void spawn () {
178         GameObject obj = constructors.values[1 + MathUtils.random(constructors.size - 2)].construct();
179         obj.moving = true;
180         obj.transform.setFromEulerAngles(MathUtils.random(360f), MathUtils.random(360f), MathUtils.random(360f));
181         obj.transform.trn(MathUtils.random(-2.5f, 2.5f), 9f, MathUtils.random(-2.5f, 2.5f));
182         obj.body.setWorldTransform(obj.transform);
183         obj.body.setUserValue(instances.size);//注意
184         obj.body.setCollisionFlags(obj.body.getCollisionFlags() | btCollisionObject.CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
185         instances.add(obj);
186         collisionWorld.addCollisionObject(obj.body, OBJECT_FLAG, GROUND_FLAG);
187     }
188 
189     @Override
190     public void render () {
191         final float delta = Math.min(1f / 30f, Gdx.graphics.getDeltaTime());
192 
193         for (GameObject obj : instances) {
194             if (obj.moving) {
195                 obj.transform.trn(0f, -delta, 0f);
196                 obj.body.setWorldTransform(obj.transform);
197             }
198         }
199 
200         collisionWorld.performDiscreteCollisionDetection();//语意 执行离散碰撞检测
201 
202         if ((spawnTimer -= delta) < 0) {
203             spawn();
204             spawnTimer = 1.5f;
205         }
206 
207         camController.update();
208 
209         Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1.f);
210         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
211 
212         modelBatch.begin(cam);
213         modelBatch.render(instances, environment);
214         modelBatch.end();
215     }
216 
217     @Override
218     public void dispose () {
219         for (GameObject obj : instances)
220             obj.dispose();
221         instances.clear();
222 
223         for (GameObject.Constructor ctor : constructors.values())
224             ctor.dispose();
225         constructors.clear();
226 
227         collisionWorld.dispose();
228         broadphase.dispose();
229         dispatcher.dispose();
230         collisionConfig.dispose();
231 
232         contactListener.dispose();
233 
234         modelBatch.dispose();
235         model.dispose();
236     }
237 
238     @Override
239     public void pause () {
240     }
241 
242     @Override
243     public void resume () {
244     }
245 
246     @Override
247     public void resize (int width, int height) {
248     }
249 }

 

转载于:https://www.cnblogs.com/hanhongmin/p/3931616.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值