Provided for angular momentum to be modified, as well as fixed some
[potpourri.git] / src / core / PhysicsObject.cpp
bloba28f7ec4b20e83d68b57431ea1f4b396cb722783
1 // Copyright 2008 Brian Caine
3 // This file is part of Potpourri.
5 // Potpourri is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // Potpourri is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTIBILITY of FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Potpourri. If not, see <http://www.gnu.org/licenses/>.
19 // NOTES:
20 // the sauce
22 #include "../../include/core/PhysicsObject.h"
23 #include "../../include/core/common.h"
25 #include <stdexcept>
27 using namespace fragrant;
29 PhysicsObject::PhysicsObject(ActorPhysics data)
31 parent = 0;
32 fixed = data.fixed;
34 if (data.fixed)
36 body = cpBodyNew(static_cast<float>(INFINITY),
37 static_cast<float>(INFINITY));
40 else
42 body = cpBodyNew(data.mass, getMoment(data.shapes, data.mass));
45 int cur;
46 for (cur = 0; cur < data.shapes.size(); cur++)
48 PhysicsShape cur_shape = data.shapes.at(cur);
49 cpShape* nshape = 0;
51 switch (cur_shape.shape)
53 case (S_Line):
55 cur_shape.data.at(0).x += data.base_position.x;
56 cur_shape.data.at(0).y += data.base_position.y;
58 cur_shape.data.at(1).x += data.base_position.x;
59 cur_shape.data.at(1).y += data.base_position.y;
61 nshape = cpSegmentShapeNew(body,
62 cpv(cur_shape.data.at(0).x, cur_shape.data.at(0).y),
63 cpv(cur_shape.data.at(1).x, cur_shape.data.at(1).y),
64 cur_shape.data.at(2).x);
65 break;
68 case (S_Circle):
70 nshape = cpCircleShapeNew(body,
71 cur_shape.data.at(0).x,
72 cpv(cur_shape.offset.x, cur_shape.offset.y));
73 break;
76 case (S_Poly):
78 cpVect vect_data[cur_shape.data.size()];
80 int cur_vect;
81 for (cur_vect = 0; cur_vect < cur_shape.data.size(); cur_vect++)
82 vect_data[cur_vect] = cpv(
83 cur_shape.data.at(cur_vect).x,
84 cur_shape.data.at(cur_vect).y);
86 nshape = cpPolyShapeNew(body, cur_shape.data.size(),
87 vect_data, cpv(cur_shape.offset.x, cur_shape.offset.y));
88 break;
92 nshape->e = cur_shape.elasticity;
93 nshape->u = cur_shape.friction;
95 shapes.push_back(nshape);
99 PhysicsObject::~PhysicsObject()
101 if (parent)
102 parent->removePhysicsObject(this);
104 if (body)
105 cpBodyFree(body);
107 int cur;
108 for (cur = 0; cur < shapes.size(); cur++)
109 if (shapes.at(cur))
110 cpShapeFree(shapes.at(cur));
113 void PhysicsObject::setPosition(ActorPair npos)
115 if (!body)
116 throw std::runtime_error("PhysicsObject::setPosition(): body is zero");
118 body->p.x = npos.x;
119 body->p.y = npos.y;
121 if (fixed && parent)
122 cpSpaceRehashStatic(parent->space);
124 return;
127 ActorPair PhysicsObject::getPosition()
129 if (!body)
130 throw std::runtime_error("PhysicsObject::getPosition(): body is zero");
132 ActorPair results;
134 results.x = body->p.x;
135 results.y = body->p.y;
137 return results;
140 void PhysicsObject::setAngle(float nangle) // i hate radians
142 cpBodySetAngle(body, toRadians(nangle));
144 if (fixed && parent)
145 cpSpaceRehashStatic(parent->space);
147 return;
150 float PhysicsObject::getAngle()
152 if (!fixed)
153 return fromRadians(body->a);
155 return 0;
158 ActorPair PhysicsObject::getCenter()
160 cpVect world = cpBodyLocal2World(body, cpv(0,0));
161 ActorPair results;
163 results.x = world.x;
164 results.y = world.y;
166 return results;
169 ActorPair PhysicsObject::Object2World(ActorPair input)
171 cpVect world = cpBodyLocal2World(body, cpv(input.x, input.y));
172 return makePair(world.x, world.y);
175 void PhysicsObject::applyImpulse(ActorPair force, ActorPair offset)
177 cpBodyApplyImpulse(body, cpv(force.x, force.y), cpv(offset.x, offset.y));
178 return;
181 ActorPair PhysicsObject::getVelocity()
183 return makePair(body->v.x, body->v.y);
186 void PhysicsObject::setVelocity(ActorPair nvelocity)
188 body->v = cpv(nvelocity.x, nvelocity.y);
190 return;
193 float PhysicsObject::getAngularVelocity()
195 return fromRadians(body->w);
198 void PhysicsObject::setAngularVelocity(float nv)
200 body->w = toRadians(nv);
201 return;
204 void PhysicsObject::addToSpace(cpSpace* space)
206 if (!fixed)
207 cpSpaceAddBody(space, body);
209 int cur;
210 for (cur = 0; cur < shapes.size(); cur++)
212 if (fixed)
213 cpSpaceAddStaticShape(space, shapes.at(cur));
214 else
215 cpSpaceAddShape(space, shapes.at(cur));
218 return;
221 void PhysicsObject::removeFromSpace(cpSpace* space)
223 if (!fixed)
224 cpSpaceRemoveBody(space, body);
226 int cur;
227 for (cur = 0; cur < shapes.size(); cur++)
229 if (fixed)
230 cpSpaceRemoveStaticShape(space, shapes.at(cur));
231 else
232 cpSpaceRemoveShape(space, shapes.at(cur));
235 return;
238 float PhysicsObject::getMoment(std::vector<PhysicsShape> shapes, float mass)
240 float results;
241 float total;
242 int count = 0;
244 int cur;
245 for (cur = 0; cur < shapes.size(); cur++)
247 PhysicsShape cur_shape = shapes.at(cur);
249 if (shapes.at(cur).shape == S_Poly)
251 cpVect vect_data[cur_shape.data.size()];
253 int cur_vect;
254 for (cur_vect = 0; cur_vect < cur_shape.data.size(); cur_vect++)
255 vect_data[cur_vect] = cpv(
256 cur_shape.data.at(cur_vect).x,
257 cur_shape.data.at(cur_vect).y);
259 total += cpMomentForPoly(mass,
260 cur_shape.data.size(), vect_data,
261 cpv(shapes.at(cur).offset.x, shapes.at(cur).offset.y));
262 count++;
265 if (shapes.at(cur).shape == S_Circle)
267 total += cpMomentForCircle(mass, cur_shape.data.at(0).x,
268 (cur_shape.data.at(0).x/2), cpv(cur_shape.offset.x,
269 cur_shape.offset.y));
270 count++;
274 return (total / count);