/examples/advanced/physics/physicsShapes/PhysicsPolygon.java
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}