PageRenderTime 29ms CodeModel.GetById 14ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 1ms

/examples/advanced/physics/physicsShapes/PhysicsPolygon.java

http://mt4j.googlecode.com/
Java | 268 lines | 156 code | 58 blank | 54 comment | 16 complexity | 65712194b5b256d49ff66d1efe1ccacd MD5 | raw file
  1package advanced.physics.physicsShapes;
  2
  3import java.util.List;
  4
  5import javax.media.opengl.glu.GLU;
  6
  7import org.jbox2d.collision.shapes.PolygonDef;
  8import org.jbox2d.common.Vec2;
  9import org.jbox2d.dynamics.Body;
 10import org.jbox2d.dynamics.BodyDef;
 11import org.jbox2d.dynamics.World;
 12import org.mt4j.MTApplication;
 13import org.mt4j.components.visibleComponents.shapes.GeometryInfo;
 14import org.mt4j.components.visibleComponents.shapes.mesh.MTTriangleMesh;
 15import org.mt4j.input.inputProcessors.componentProcessors.rotateProcessor.RotateProcessor;
 16import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleProcessor;
 17import org.mt4j.util.math.Vector3D;
 18import org.mt4j.util.math.Vertex;
 19import org.mt4j.util.opengl.GluTrianglulator;
 20
 21import processing.core.PApplet;
 22
 23public class PhysicsPolygon extends MTTriangleMesh implements IPhysicsComponent {
 24	private float angle;
 25	private World world;
 26	private Body body;
 27	private float density;
 28	private float friction;
 29	private float restituion;
 30	
 31	public PhysicsPolygon(Vertex[] vertices, Vector3D position, PApplet applet,
 32			World world, float density, float friction, float restitution, float worldScale
 33	) {
 34		super(applet, new GeometryInfo(applet, new Vertex[]{}), false);
 35		this.angle = 0;
 36		this.world = world;
 37		this.density = density;
 38		this.friction = friction;
 39		this.restituion = restitution;
 40		
 41		this.setGestureAllowance(ScaleProcessor.class, false);
 42		this.setGestureAllowance(RotateProcessor.class, false);
 43		
 44		Vertex.scaleVectorArray(vertices, Vector3D.ZERO_VECTOR, 1f/worldScale, 1f/worldScale, 1);
 45		
 46		position.scaleLocal(1f/worldScale); //FIXME REALLY?
 47		
 48    	GluTrianglulator triangulator = new GluTrianglulator(applet);
 49		List<Vertex> physicsTris = triangulator.tesselate(vertices, GLU.GLU_TESS_WINDING_NONZERO);
 50		Vertex[] triangulatedBodyVerts = physicsTris.toArray(new Vertex[physicsTris.size()]);
 51		triangulator.deleteTess();
 52		//Set the triangulated vertices as the polygons (mesh's) vertices
 53		this.setGeometryInfo(new GeometryInfo(applet, triangulatedBodyVerts));
 54		
 55		this.translate(position);
 56		Vector3D realBodyCenter = this.getCenterPointGlobal(); //FIXME geht nur if detached from world //rename futurebodycenter?
 57		//Reset position
 58		this.translate(position.getScaled(-1));
 59		
 60		//Now get the position where the global center will be after setting the shape at the desired position
 61		this.setPositionGlobal(position);
 62		Vector3D meshCenterAtPosition = this.getCenterPointGlobal();
 63		
 64		//Compute the distance we would have to move the vertices for the body creation
 65		//so that the body.position(center) is at the same position as our mesh center
 66		Vector3D realBodyCenterToMeshCenter = meshCenterAtPosition.getSubtracted(realBodyCenter);
 67		//System.out.println("Diff:" +  realBodyCenterToMeshCenter);
 68		
 69		//Move the vertices so the body position is at the center of the shape 
 70		Vertex.translateVectorArray(triangulatedBodyVerts, realBodyCenterToMeshCenter);
 71		
 72		this.setGeometryInfo(new GeometryInfo(applet, triangulatedBodyVerts));
 73		
 74//		MTPolygon p = new MTPolygon(vertices, applet);
 75//		p.translate(position);
 76////		p.setPositionGlobal(position);
 77//		Vector3D realBodyCenter = p.getCenterPointGlobal(); //FIXME geht nur if detached from world //rename futurebodycenter?
 78//		//Reset position
 79//		p.translate(position.getScaled(-1));
 80//		
 81//		//Now get the position where the global center will be after setting the shape at the desired position
 82//		p.setPositionGlobal(position);
 83//		Vector3D meshCenterAtPosition = p.getCenterPointGlobal();
 84//		
 85//		//Compute the distance we would have to move the vertices for the body creation
 86//		//so that the body.position(center) is at the same position as our mesh center
 87//		Vector3D realBodyCenterToMeshCenter = meshCenterAtPosition.getSubtracted(realBodyCenter);
 88//		//System.out.println("Diff:" +  realBodyCenterToMeshCenter);
 89//		
 90//		//Move the vertices so the body position is at the center of the shape 
 91//		Vertex.translateVectorArray(vertices, realBodyCenterToMeshCenter);
 92		
 93		Vertex.translateVectorArray(vertices, realBodyCenterToMeshCenter);
 94		
 95		//Create vertex structure for creation of decomposition polygon (use the translated vertices)
 96		float xArr[] = new float[vertices.length];
 97		float yArr[] = new float[vertices.length];
 98		for (int i = 0; i < vertices.length; i++) {
 99			Vertex v = vertices[i];
100			xArr[i] = v.x;
101			yArr[i] = v.y;
102		}
103		//Create a polygon too see if its simple and eventually decompose it
104		org.jbox2d.util.nonconvex.Polygon myPoly = new org.jbox2d.util.nonconvex.Polygon(xArr, yArr);
105		
106		PolygonDef pd = new PolygonDef();
107    	if (density != 0.0f){
108    		pd.density 		= density;
109    		pd.friction 	= friction;
110    		pd.restitution 	= restituion;
111		}
112    	
113		//Create polygon body
114		BodyDef dymBodyDef = new BodyDef();
115//		dymBodyDef.position = new Vec2(position.x /worldScale, position.y /worldScale);
116		dymBodyDef.position = new Vec2(position.x , position.y );
117		this.bodyDefB4CreationCallback(dymBodyDef);
118		this.body = world.createBody(dymBodyDef);
119		
120//    	GluTrianglulator triangulator = new GluTrianglulator(applet);
121//		List<Vertex> physicsTris = triangulator.tesselate(vertices, GLU.GLU_TESS_WINDING_NONZERO);
122//		Vertex[] triangulatedBodyVerts = physicsTris.toArray(new Vertex[physicsTris.size()]);
123//		triangulator.deleteTess();
124		
125//		//Set the triangulated vertices as the polygons (mesh's) vertices
126//		this.setGeometryInfo(new GeometryInfo(applet, triangulatedBodyVerts));
127		
128		//Decompose poly and add verts to phys body if possible
129    	int success = org.jbox2d.util.nonconvex.Polygon.decomposeConvexAndAddTo(myPoly, this.body, pd); 
130    	
131    	if (success != -1){
132    		System.out.println("-> Ear clipping SUCCESSFUL -> Using triangulated and polygonized shape for b2d.");
133    		this.body.setMassFromShapes();
134    		this.body.setUserData(this);
135	    	this.setUserData("box2d", this.body); //TODO rename userData
136			//Performance hit! but prevents object from sticking to another sometimes
137//			theBody.setBullet(true);
138    	}else{
139    		System.out.println("-> Ear clipping had an ERROR - trying again by triangulating shape for b2d with GLU-Triangulator");
140//    		GluTrianglulator triangulator = new GluTrianglulator(app);
141//    		List<Vertex> physicsTris = triangulator.tesselate(bodyVerts, GLU.GLU_TESS_WINDING_NONZERO);
142//    		Vertex[] triangulatedBodyVerts = physicsTris.toArray(new Vertex[physicsTris.size()]);
143    		//System.out.println("GLU tris created: " + triangulatedBodyVerts.length);
144    		
145    		//Cap the max triangles - dont use anymore triangles for the physics body..
146    		int cap = 400;
147    		if (triangulatedBodyVerts.length > cap){
148    			//System.err.println("OVER cap! -> capping!");
149    			Vertex[] tmp = new Vertex[cap];
150    			System.arraycopy(triangulatedBodyVerts, 0, tmp, 0, cap);
151    			triangulatedBodyVerts = tmp;
152    		}
153    		
154    		//Create polygon body
155    		world.destroyBody(this.body);
156    		dymBodyDef = new BodyDef();
157    		dymBodyDef.position = new Vec2(position.x, position.y);
158    		this.bodyDefB4CreationCallback(dymBodyDef);
159    		this.body = world.createBody(dymBodyDef);
160    		for (int i = 0; i < triangulatedBodyVerts.length/3; i++) {
161    			//Create polygon definition
162    			PolygonDef polyDef = new PolygonDef();
163    			if (density != 0.0f){
164    				polyDef.density 		= density;
165    				polyDef.friction 		= friction;
166    				polyDef.restitution 	= restituion;
167    			}
168    			this.polyDefB4CreationCallback(polyDef); //FIXME TEST
169    			
170    			//Add triangle vertices
171    			Vertex vertex1 = triangulatedBodyVerts[i*3];
172    			Vertex vertex2 = triangulatedBodyVerts[i*3+1];
173    			Vertex vertex3 = triangulatedBodyVerts[i*3+2];
174    			polyDef.addVertex(new Vec2(vertex1.x, vertex1.y));
175    			polyDef.addVertex(new Vec2(vertex2.x, vertex2.y));
176    			polyDef.addVertex(new Vec2(vertex3.x, vertex3.y));
177    			//Add poly to body
178    			this.body.createShape(polyDef);
179    		}
180    		this.body.setMassFromShapes();
181    		//FIXME TEST - performance hit!?
182    		//theBody.setBullet(true);
183    		this.body.setUserData(this);
184    		this.setUserData("box2d", this.body); //TODO rename userData
185    	}
186		
187//    	p.destroy();
188	}
189	
190	
191	protected void polyDefB4CreationCallback(PolygonDef def){
192		
193	}
194	
195	protected void bodyDefB4CreationCallback(BodyDef def){
196		
197	}
198	
199	
200	//@Override
201	public void rotateZGlobal(Vector3D rotationPoint, float degree) {
202		angle += degree;
203		super.rotateZGlobal(rotationPoint, degree);
204	}
205	public float getAngle() {
206		return angle;
207	}
208	public void setCenterRotation(float angle){
209		float degreeAngle = MTApplication.degrees(angle);
210		float oldAngle = this.getAngle();
211		float diff = degreeAngle-oldAngle;
212		//System.out.println("Old angle: " + oldAngle + " new angle:" + degreeAngle + " diff->" +  diff);
213		this.rotateZGlobal(this.getCenterPointGlobal(), diff);
214	}
215	
216	//@Override
217	protected void destroyComponent() {
218		Object o = this.getUserData("box2d");
219		if (o != null && o instanceof Body){ 
220			Body box2dBody = (Body)o;
221			boolean exists = false;
222			for (Body body = world.getBodyList(); body != null; body = body.getNext()) {
223				if (body.equals(this.body))
224					exists = true;//Delete later to avoid concurrent modification
225			}
226			if (exists)
227				box2dBody.getWorld().destroyBody(box2dBody);
228		}
229		super.destroyComponent();
230	}
231
232
233
234
235	public World getWorld() {
236		return world;
237	}
238
239
240
241
242	public Body getBody() {
243		return body;
244	}
245
246
247
248
249	public float getDensity() {
250		return density;
251	}
252
253
254
255
256	public float getFriction() {
257		return friction;
258	}
259
260
261
262
263	public float getRestituion() {
264		return restituion;
265	}
266	
267	
268}