Many updates, see CHANGLOG diff
[rokon:rokon.git] / src / com / stickycoding / rokon / Physics.java
1 package com.stickycoding.rokon;\r
2 \r
3 import java.io.BufferedReader;\r
4 import java.io.InputStream;\r
5 import java.io.InputStreamReader;\r
6 \r
7 import org.json.JSONArray;\r
8 import org.json.JSONObject;\r
9 \r
10 import com.badlogic.gdx.math.Vector2;\r
11 import com.badlogic.gdx.physics.box2d.Body;\r
12 import com.badlogic.gdx.physics.box2d.BodyDef;\r
13 import com.badlogic.gdx.physics.box2d.CircleShape;\r
14 import com.badlogic.gdx.physics.box2d.Contact;\r
15 import com.badlogic.gdx.physics.box2d.FixtureDef;\r
16 import com.badlogic.gdx.physics.box2d.PolygonShape;\r
17 import com.badlogic.gdx.physics.box2d.Shape;\r
18 import com.badlogic.gdx.physics.box2d.World;\r
19 \r
20 /**\r
21  * Physics.java\r
22  * Contains some static variables for the Box2D engine\r
23  * (Kindly written by the libgdx project)\r
24  * \r
25  * @author Richard\r
26  */\r
27 \r
28 public class Physics {\r
29         \r
30         /**\r
31          * The Box2D World which is in use\r
32          */\r
33         public static World world;\r
34         \r
35         /**\r
36          * Creates a Body from a .json file\r
37          * \r
38          * @param filename\r
39          * @param obj DimensionalObject to map this to\r
40          * @return\r
41          */\r
42         public static PhysicsDef fromFile(String filename, DimensionalObject obj) {\r
43                 PhysicsDef physicsDef = null;\r
44                 try {\r
45                         InputStream stream = Rokon.currentActivity.getAssets().open(filename);\r
46                         InputStreamReader reader = new InputStreamReader(stream);\r
47                         BufferedReader in = new BufferedReader(reader);\r
48                         String content = "";\r
49                         String line;\r
50                         line = in.readLine();\r
51                         while(line != null) {\r
52                                 content += line + "\n";\r
53                                 line = in.readLine();\r
54                         }\r
55                         stream.close();\r
56                         \r
57                         JSONObject jsonObj = new JSONObject(content);                   \r
58                         String type = jsonObj.getString("type");\r
59                         if(!jsonObj.has("type")) {\r
60                                 throw new Exception("Missing type");\r
61                         }\r
62                         JSONArray fixtures = jsonObj.getJSONArray("fixtures");\r
63                         if(fixtures == null) {\r
64                                 throw new Exception("No fixtures definition, what's the point?");\r
65                         }\r
66                         \r
67                         physicsDef = new PhysicsDef();\r
68                         \r
69                         BodyDef bodyDef = new BodyDef();\r
70                         if(type.equals("dynamic")) bodyDef.type = BodyDef.BodyType.DynamicBody;\r
71                         if(type.equals("kinematic")) bodyDef.type = BodyDef.BodyType.KinematicBody;\r
72                         if(type.equals("static")) bodyDef.type = BodyDef.BodyType.StaticBody;\r
73                         if(bodyDef.type == null) throw new Exception("Unknown type=" + type);\r
74                 \r
75                         physicsDef.bodyDef = bodyDef;\r
76                         \r
77                         \r
78                         for(int i = 0; i < fixtures.length(); i++) {\r
79                                 FixtureDef fixtureDef = new FixtureDef();\r
80                                 Shape shape = null;\r
81                                 \r
82                                 JSONObject jsonFixture = fixtures.getJSONObject(i);\r
83                                 JSONObject jsonShape = jsonFixture.getJSONObject("shape");\r
84                                 \r
85                                 if(jsonShape.getString("type").equals("circle")) {\r
86                                         shape = new CircleShape();\r
87                                         CircleShape circleShape = (CircleShape)shape;\r
88                                         circleShape.setPosition(new Vector2((float)jsonShape.getDouble("x") * obj.getWidth(), (float)jsonShape.getDouble("y") * obj.getHeight()));\r
89                                         circleShape.setRadius((float)jsonShape.getDouble("radius") * obj.getHeight());\r
90                                 }\r
91                                 \r
92                                 if(jsonShape.getString("type").equals("polygon")) {\r
93                                         JSONArray jsonX = jsonShape.getJSONArray("x");\r
94                                         JSONArray jsonY = jsonShape.getJSONArray("y");\r
95                                         shape = new PolygonShape();\r
96                                         PolygonShape polyShape = (PolygonShape)shape;\r
97                                         Vector2[] vertices = new Vector2[jsonX.length()];\r
98                                         for(int j = 0; j < vertices.length; j++) {\r
99                                                 vertices[j] = new Vector2((float)jsonX.getDouble(j) * obj.getWidth(), (float)jsonY.getDouble(j) * obj.getHeight());\r
100                                                 Debug.print("added vertex x=" + vertices[j].x + " y=" +  vertices[j].y);\r
101                                         }\r
102                                         polyShape.set(vertices);\r
103                                 }\r
104 \r
105                                 if(jsonFixture.has("friction")) fixtureDef.friction = (float)jsonFixture.getDouble("friction");\r
106                                 if(jsonFixture.has("restitution")) fixtureDef.restitution = (float)jsonFixture.getDouble("restitution");\r
107                                 if(jsonFixture.has("density")) fixtureDef.density = (float)jsonFixture.getDouble("density");\r
108                                 \r
109                                 fixtureDef.shape = shape;\r
110                                 \r
111                                 physicsDef.add(shape, fixtureDef);\r
112                         }\r
113                         \r
114                         \r
115                 } catch (Exception e) {\r
116                         Debug.error("Error in bodyFromFile " + filename);\r
117                         e.printStackTrace();\r
118                 }\r
119                 return physicsDef;\r
120         }\r
121         \r
122         /**\r
123          * Creates an active Body from a PhysicsDef\r
124          * \r
125          * @param physicsDef a filled PhysicsDef object\r
126          * @param obj the DimensionalObject to map this to\r
127          * @return the created Body\r
128          */\r
129         public static Body bodyFromPhysicsDef(PhysicsDef physicsDef, DimensionalObject obj) {\r
130                 Body body = null;\r
131 \r
132                 physicsDef.bodyDef.position.x = obj.getX() + obj.getHeight() / 2;\r
133                 physicsDef.bodyDef.position.y = obj.getY() + obj.getWidth() / 2;\r
134                 \r
135                 body = world.createBody(physicsDef.bodyDef);\r
136                 \r
137                 for(int i = 0; i < physicsDef.fixtureCount; i++) {\r
138                         body.createFixture(physicsDef.fixtureDefs[i]);\r
139                 }               \r
140                 \r
141                 return body;\r
142         }\r
143         \r
144         public static boolean bodyContact(Contact contact, Body body1, Body body2) {\r
145                 if(body1.getFixtureList().contains(contact.getFixtureA()) && body2.getFixtureList().contains(contact.getFixtureB())) {\r
146                         return true;\r
147                 } else if(body1.getFixtureList().contains(contact.getFixtureB()) && body2.getFixtureList().contains(contact.getFixtureA())) {\r
148                         return true;\r
149                 }\r
150                 return false;\r
151         }\r
152 \r
153 }\r