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/>.
22 #include "../../include/core/PhysicsObject.h"
23 #include "../../include/core/common.h"
27 using namespace fragrant
;
29 PhysicsObject::PhysicsObject(ActorPhysics data
)
36 body
= cpBodyNew(static_cast<float>(INFINITY
),
37 static_cast<float>(INFINITY
));
42 body
= cpBodyNew(data
.mass
, getMoment(data
.shapes
, data
.mass
));
46 for (cur
= 0; cur
< data
.shapes
.size(); cur
++)
48 PhysicsShape cur_shape
= data
.shapes
.at(cur
);
51 switch (cur_shape
.shape
)
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
);
70 nshape
= cpCircleShapeNew(body
,
71 cur_shape
.data
.at(0).x
,
72 cpv(cur_shape
.offset
.x
, cur_shape
.offset
.y
));
78 cpVect vect_data
[cur_shape
.data
.size()];
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
));
92 nshape
->e
= cur_shape
.elasticity
;
93 nshape
->u
= cur_shape
.friction
;
95 shapes
.push_back(nshape
);
99 PhysicsObject::~PhysicsObject()
102 parent
->removePhysicsObject(this);
108 for (cur
= 0; cur
< shapes
.size(); cur
++)
110 cpShapeFree(shapes
.at(cur
));
113 void PhysicsObject::setPosition(ActorPair npos
)
116 throw std::runtime_error("PhysicsObject::setPosition(): body is zero");
122 cpSpaceRehashStatic(parent
->space
);
127 ActorPair
PhysicsObject::getPosition()
130 throw std::runtime_error("PhysicsObject::getPosition(): body is zero");
134 results
.x
= body
->p
.x
;
135 results
.y
= body
->p
.y
;
140 void PhysicsObject::setAngle(float nangle
) // i hate radians
142 cpBodySetAngle(body
, toRadians(nangle
));
145 cpSpaceRehashStatic(parent
->space
);
150 float PhysicsObject::getAngle()
153 return fromRadians(body
->a
);
158 ActorPair
PhysicsObject::getCenter()
160 cpVect world
= cpBodyLocal2World(body
, cpv(0,0));
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
));
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
);
193 float PhysicsObject::getAngularVelocity()
195 return fromRadians(body
->w
);
198 void PhysicsObject::setAngularVelocity(float nv
)
200 body
->w
= toRadians(nv
);
204 void PhysicsObject::addToSpace(cpSpace
* space
)
207 cpSpaceAddBody(space
, body
);
210 for (cur
= 0; cur
< shapes
.size(); cur
++)
213 cpSpaceAddStaticShape(space
, shapes
.at(cur
));
215 cpSpaceAddShape(space
, shapes
.at(cur
));
221 void PhysicsObject::removeFromSpace(cpSpace
* space
)
224 cpSpaceRemoveBody(space
, body
);
227 for (cur
= 0; cur
< shapes
.size(); cur
++)
230 cpSpaceRemoveStaticShape(space
, shapes
.at(cur
));
232 cpSpaceRemoveShape(space
, shapes
.at(cur
));
238 float PhysicsObject::getMoment(std::vector
<PhysicsShape
> shapes
, float mass
)
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()];
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
));
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
));
274 return (total
/ count
);