• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 package com.badlogic.gdx.tests.bullet;
18 
19 import java.nio.ShortBuffer;
20 
21 import com.badlogic.gdx.Gdx;
22 import com.badlogic.gdx.graphics.VertexAttributes.Usage;
23 import com.badlogic.gdx.graphics.g3d.Model;
24 import com.badlogic.gdx.graphics.g3d.model.MeshPart;
25 import com.badlogic.gdx.math.Vector3;
26 import com.badlogic.gdx.physics.bullet.collision.btAxisSweep3;
27 import com.badlogic.gdx.physics.bullet.collision.btCollisionDispatcher;
28 import com.badlogic.gdx.physics.bullet.collision.btCollisionObject;
29 import com.badlogic.gdx.physics.bullet.collision.btDefaultCollisionConfiguration;
30 import com.badlogic.gdx.physics.bullet.dynamics.btSequentialImpulseConstraintSolver;
31 import com.badlogic.gdx.physics.bullet.softbody.btSoftBody;
32 import com.badlogic.gdx.physics.bullet.softbody.btSoftBodyRigidBodyCollisionConfiguration;
33 import com.badlogic.gdx.physics.bullet.softbody.btSoftBodyWorldInfo;
34 import com.badlogic.gdx.physics.bullet.softbody.btSoftRigidDynamicsWorld;
35 import com.badlogic.gdx.utils.BufferUtils;
36 
37 /** @author xoppa */
38 public class SoftMeshTest extends BaseBulletTest {
39 	btSoftBodyWorldInfo worldInfo;
40 	btSoftBody softBody;
41 	Model model;
42 	BulletEntity entity;
43 	ShortBuffer indexMap;
44 	Vector3 tmpV = new Vector3();
45 	int positionOffset;
46 	int normalOffset;
47 
48 	@Override
createWorld()49 	public BulletWorld createWorld () {
50 		btDefaultCollisionConfiguration collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
51 		btCollisionDispatcher dispatcher = new btCollisionDispatcher(collisionConfiguration);
52 		btAxisSweep3 broadphase = new btAxisSweep3(tmpV1.set(-1000, -1000, -1000), tmpV2.set(1000, 1000, 1000), 1024);
53 		btSequentialImpulseConstraintSolver solver = new btSequentialImpulseConstraintSolver();
54 		btSoftRigidDynamicsWorld dynamicsWorld = new btSoftRigidDynamicsWorld(dispatcher, broadphase, solver,
55 			collisionConfiguration);
56 
57 		worldInfo = new btSoftBodyWorldInfo();
58 		worldInfo.setBroadphase(broadphase);
59 		worldInfo.setDispatcher(dispatcher);
60 		worldInfo.getSparsesdf().Initialize();
61 
62 		return new BulletWorld(collisionConfiguration, dispatcher, broadphase, solver, dynamicsWorld);
63 	}
64 
65 	@Override
create()66 	public void create () {
67 		super.create();
68 
69 		world.maxSubSteps = 20;
70 
71 		world.add("ground", 0f, 0f, 0f).setColor(0.25f + 0.5f * (float)Math.random(), 0.25f + 0.5f * (float)Math.random(),
72 			0.25f + 0.5f * (float)Math.random(), 1f);
73 
74 		// Note: not every model is suitable for a one on one translation with a soft body, a better model might be added later.
75 		model = objLoader.loadModel(Gdx.files.internal("data/wheel.obj"));
76 		MeshPart meshPart = model.nodes.get(0).parts.get(0).meshPart;
77 
78 		meshPart.mesh.scale(6, 6, 6);
79 
80 		indexMap = BufferUtils.newShortBuffer(meshPart.size);
81 
82 		positionOffset = meshPart.mesh.getVertexAttribute(Usage.Position).offset;
83 		normalOffset = meshPart.mesh.getVertexAttribute(Usage.Normal).offset;
84 
85 		softBody = new btSoftBody(worldInfo, meshPart.mesh.getVerticesBuffer(), meshPart.mesh.getVertexSize(), positionOffset,
86 			normalOffset, meshPart.mesh.getIndicesBuffer(), meshPart.offset, meshPart.size, indexMap, 0);
87 		// Set mass of the first vertex to zero so its unmovable, comment out this line to make it a fully dynamic body.
88 		softBody.setMass(0, 0);
89 		com.badlogic.gdx.physics.bullet.softbody.btSoftBody.Material pm = softBody.appendMaterial();
90 		pm.setKLST(0.2f);
91 		pm.setFlags(0);
92 		softBody.generateBendingConstraints(2, pm);
93 		// Be careful increasing iterations, it decreases performance (but increases accuracy).
94 		softBody.setConfig_piterations(7);
95 		softBody.setConfig_kDF(0.2f);
96 		softBody.randomizeConstraints();
97 		softBody.setTotalMass(1);
98 		softBody.translate(tmpV.set(1, 5, 1));
99 		((btSoftRigidDynamicsWorld)(world.collisionWorld)).addSoftBody(softBody);
100 
101 		world.add(entity = new BulletEntity(model, (btCollisionObject)null, 1, 5, 1));
102 	}
103 
104 	@Override
dispose()105 	public void dispose () {
106 		((btSoftRigidDynamicsWorld)(world.collisionWorld)).removeSoftBody(softBody);
107 		softBody.dispose();
108 		softBody = null;
109 		indexMap = null;
110 
111 		super.dispose();
112 
113 		worldInfo.dispose();
114 		worldInfo = null;
115 		model.dispose();
116 		model = null;
117 	}
118 
119 	@Override
render()120 	public void render () {
121 		if (world.renderMeshes) {
122 			MeshPart meshPart = model.nodes.get(0).parts.get(0).meshPart;
123 			softBody.getVertices(meshPart.mesh.getVerticesBuffer(), meshPart.mesh.getVertexSize(), positionOffset, normalOffset,
124 				meshPart.mesh.getIndicesBuffer(), meshPart.offset, meshPart.size, indexMap, 0);
125 			softBody.getWorldTransform(entity.transform);
126 		}
127 		super.render();
128 	}
129 
130 	@Override
tap(float x, float y, int count, int button)131 	public boolean tap (float x, float y, int count, int button) {
132 		shoot(x, y, 20f);
133 		return true;
134 	}
135 }
136