Panda3D
bulletHingeConstraint.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file bulletHingeConstraint.cxx
10  * @author enn0x
11  * @date 2010-03-01
12  */
13 
14 #include "bulletHingeConstraint.h"
15 
16 #include "bulletRigidBodyNode.h"
17 #include "bulletWorld.h"
18 
19 #include "deg_2_rad.h"
20 
21 TypeHandle BulletHingeConstraint::_type_handle;
22 
23 /**
24  * Creates a hinge constraint which connects one rigid body with some fixe
25  * dpoint in the world.
26  */
29  const TransformState *ts_a,
30  bool use_frame_a) {
31 
32  btRigidBody *ptr_a = btRigidBody::upcast(node_a->get_object());
33  btTransform frame_a = TransformState_to_btTrans(ts_a);
34 
35  _constraint = new btHingeConstraint(*ptr_a, frame_a, use_frame_a);
36 }
37 
38 /**
39  * Constructs a hinge constraint which connects two rigid bodies.
40  */
43  const BulletRigidBodyNode *node_b,
44  const TransformState *ts_a,
45  const TransformState *ts_b,
46  bool use_frame_a) {
47 
48  btRigidBody *ptr_a = btRigidBody::upcast(node_a->get_object());
49  btTransform frame_a = TransformState_to_btTrans(ts_a);
50 
51  btRigidBody *ptr_b = btRigidBody::upcast(node_b->get_object());
52  btTransform frame_b = TransformState_to_btTrans(ts_b);
53 
54  _constraint = new btHingeConstraint(*ptr_a, *ptr_b, frame_a, frame_b, use_frame_a);
55 }
56 
57 /**
58  * Creates a hinge constraint in the same way as the other constructor, but
59  * uses the world as second body so that node_a is fixed to some point in mid-
60  * air for example.
61  */
64  const LPoint3 &pivot_a,
65  const LVector3 &axis_a,
66  bool use_frame_a) {
67 
68  btRigidBody *ptr_a = btRigidBody::upcast(node_a->get_object());
69  btVector3 pos_a = LVecBase3_to_btVector3(pivot_a);
70  btVector3 vec_a = LVecBase3_to_btVector3(axis_a);
71 
72  _constraint = new btHingeConstraint(*ptr_a, pos_a, vec_a, use_frame_a);
73 }
74 
75 /**
76  * Creates a hinge connecting node_a to node_b. The pivot point is the point
77  * at which the body is fixed to the constraint. In other words: It specifies
78  * where on each body the rotation axis should be. This axis is specified
79  * using axis_a and axis_b. Remember, everything is specified in the bodies
80  * own coordinate system!
81  */
84  const BulletRigidBodyNode *node_b,
85  const LPoint3 &pivot_a,
86  const LPoint3 &pivot_b,
87  const LVector3 &axis_a,
88  const LVector3 &axis_b,
89  bool use_frame_a) {
90 
91  btRigidBody *ptr_a = btRigidBody::upcast(node_a->get_object());
92  btVector3 pos_a = LVecBase3_to_btVector3(pivot_a);
93  btVector3 vec_a = LVecBase3_to_btVector3(axis_a);
94 
95  btRigidBody *ptr_b = btRigidBody::upcast(node_b->get_object());
96  btVector3 pos_b = LVecBase3_to_btVector3(pivot_b);
97  btVector3 vec_b = LVecBase3_to_btVector3(axis_b);
98 
99  _constraint = new btHingeConstraint(*ptr_a, *ptr_b, pos_a, pos_b, vec_a, vec_b, use_frame_a);
100 }
101 
102 /**
103  *
104  */
105 btTypedConstraint *BulletHingeConstraint::
106 ptr() const {
107 
108  return _constraint;
109 }
110 
111 /**
112  *
113  */
114 void BulletHingeConstraint::
115 set_angular_only(bool value) {
116  LightMutexHolder holder(BulletWorld::get_global_lock());
117 
118  return _constraint->setAngularOnly(value);
119 }
120 
121 /**
122  *
123  */
124 bool BulletHingeConstraint::
125 get_angular_only() const {
126  LightMutexHolder holder(BulletWorld::get_global_lock());
127 
128  return _constraint->getAngularOnly();
129 }
130 
131 /**
132  * Sets the lower and upper rotational limits in degrees.
133  */
135 set_limit(PN_stdfloat low, PN_stdfloat high, PN_stdfloat softness, PN_stdfloat bias, PN_stdfloat relaxation) {
136  LightMutexHolder holder(BulletWorld::get_global_lock());
137 
138  low = deg_2_rad(low);
139  high = deg_2_rad(high);
140 
141  _constraint->setLimit(low, high, softness, bias, relaxation);
142 }
143 
144 /**
145  * Sets the hinge's rotation axis in world coordinates.
146  */
148 set_axis(const LVector3 &axis) {
149  LightMutexHolder holder(BulletWorld::get_global_lock());
150 
151  nassertv(!axis.is_nan());
152 
153  btVector3 v = LVecBase3_to_btVector3(axis);
154  _constraint->setAxis(v);
155 }
156 
157 /**
158  * Returns the lower angular limit in degrees.
159  */
160 PN_stdfloat BulletHingeConstraint::
161 get_lower_limit() const {
162  LightMutexHolder holder(BulletWorld::get_global_lock());
163 
164  return rad_2_deg(_constraint->getLowerLimit());
165 }
166 
167 /**
168  * Returns the upper angular limit in degrees.
169  */
170 PN_stdfloat BulletHingeConstraint::
171 get_upper_limit() const {
172  LightMutexHolder holder(BulletWorld::get_global_lock());
173 
174  return rad_2_deg(_constraint->getUpperLimit());
175 }
176 
177 /**
178  * Returns the angle between node_a and node_b in degrees.
179  */
180 PN_stdfloat BulletHingeConstraint::
181 get_hinge_angle() {
182  LightMutexHolder holder(BulletWorld::get_global_lock());
183 
184  return rad_2_deg(_constraint->getHingeAngle());
185 }
186 
187 /**
188  * Applies an impulse to the constraint so that the angle changes at
189  * target_velocity where max_impulse is the maximum impulse that is used for
190  * achieving the specified velocity.
191  *
192  * Note that the target_velocity is in radians/second, not degrees.
193  */
195 enable_angular_motor(bool enable, PN_stdfloat target_velocity, PN_stdfloat max_impulse) {
196  LightMutexHolder holder(BulletWorld::get_global_lock());
197 
198  _constraint->enableAngularMotor(enable, target_velocity, max_impulse);
199 }
200 
201 /**
202  *
203  */
204 void BulletHingeConstraint::
205 enable_motor(bool enable) {
206  LightMutexHolder holder(BulletWorld::get_global_lock());
207 
208  _constraint->enableMotor(enable);
209 }
210 
211 /**
212  * Sets the maximum impulse used to achieve the velocity set in
213  * enable_angular_motor.
214  */
216 set_max_motor_impulse(PN_stdfloat max_impulse) {
217  LightMutexHolder holder(BulletWorld::get_global_lock());
218 
219  _constraint->setMaxMotorImpulse(max_impulse);
220 }
221 
222 /**
223  *
224  */
225 void BulletHingeConstraint::
226 set_motor_target(const LQuaternion &quat, PN_stdfloat dt) {
227  LightMutexHolder holder(BulletWorld::get_global_lock());
228 
229  _constraint->setMotorTarget(LQuaternion_to_btQuat(quat), dt);
230 }
231 
232 /**
233  *
234  */
235 void BulletHingeConstraint::
236 set_motor_target(PN_stdfloat target_angle, PN_stdfloat dt) {
237  LightMutexHolder holder(BulletWorld::get_global_lock());
238 
239  _constraint->setMotorTarget(target_angle, dt);
240 }
241 
242 /**
243  *
244  */
245 void BulletHingeConstraint::
246 set_frames(const TransformState *ts_a, const TransformState *ts_b) {
247  LightMutexHolder holder(BulletWorld::get_global_lock());
248 
249  btTransform frame_a = TransformState_to_btTrans(ts_a);
250  btTransform frame_b = TransformState_to_btTrans(ts_b);
251 
252  _constraint->setFrames(frame_a, frame_b);
253 }
254 
255 /**
256  *
257  */
258 CPT(TransformState) BulletHingeConstraint::
259 get_frame_a() const {
260  LightMutexHolder holder(BulletWorld::get_global_lock());
261 
262  return btTrans_to_TransformState(_constraint->getAFrame());
263 }
264 
265 /**
266  *
267  */
268 CPT(TransformState) BulletHingeConstraint::
269 get_frame_b() const {
270  LightMutexHolder holder(BulletWorld::get_global_lock());
271 
272  return btTrans_to_TransformState(_constraint->getBFrame());
273 }
void set_axis(const LVector3 &axis)
Sets the hinge's rotation axis in world coordinates.
Indicates a coordinate-system transform on vertices.
void enable_angular_motor(bool enable, PN_stdfloat target_velocity, PN_stdfloat max_impulse)
Applies an impulse to the constraint so that the angle changes at target_velocity where max_impulse i...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_max_motor_impulse(PN_stdfloat max_impulse)
Sets the maximum impulse used to achieve the velocity set in enable_angular_motor.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Similar to MutexHolder, but for a light mutex.
void set_limit(PN_stdfloat low, PN_stdfloat high, PN_stdfloat softness=0.9f, PN_stdfloat bias=0.3f, PN_stdfloat relaxation=1.0f)
Sets the lower and upper rotational limits in degrees.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BulletHingeConstraint(const BulletRigidBodyNode *node_a, const LPoint3 &pivot_a, const LVector3 &axis_a, bool use_frame_a=false)
Creates a hinge constraint in the same way as the other constructor, but uses the world as second bod...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81