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 }

 

你可能感兴趣的:(libgdx)