39 BulletBodyNode(
const char *name) :
PandaNode(name) {
42 _shape =
new btEmptyShape();
57 _shapes = copy._shapes;
58 if (copy._shape && copy._shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
60 btCompoundShape *shape =
new btCompoundShape;
63 btCompoundShape *copy_shape = (btCompoundShape *)copy._shape;
64 int num_children = copy_shape->getNumChildShapes();
65 for (
int i = 0; i < num_children; ++i) {
66 shape->addChildShape(copy_shape->getChildTransform(i),
67 copy_shape->getChildShape(i));
70 else if (copy._shape && copy._shape->getShapeType() == EMPTY_SHAPE_PROXYTYPE) {
71 _shape =
new btEmptyShape();
161 void BulletBodyNode::
162 do_output(std::ostream &out)
const {
164 PandaNode::output(out);
166 out <<
" (" << _shapes.size() <<
" shapes)";
168 out << (get_object()->isActive() ?
" active" :
" inactive");
170 if (get_object()->isStaticObject()) out <<
" static";
171 if (get_object()->isKinematicObject()) out <<
" kinematic";
177 void BulletBodyNode::
178 output(std::ostream &out)
const {
187 void BulletBodyNode::
188 set_collision_flag(
int flag,
bool value) {
191 int flags = get_object()->getCollisionFlags();
200 get_object()->setCollisionFlags(flags);
206 bool BulletBodyNode::
207 get_collision_flag(
int flag)
const {
210 return (get_object()->getCollisionFlags() & flag) ? true :
false;
216 bool BulletBodyNode::
220 return get_object()->isStaticObject();
226 bool BulletBodyNode::
227 is_kinematic()
const {
230 return get_object()->isKinematicObject();
236 PN_stdfloat BulletBodyNode::
237 get_restitution()
const {
240 return get_object()->getRestitution();
246 void BulletBodyNode::
247 set_restitution(PN_stdfloat restitution) {
250 return get_object()->setRestitution(restitution);
256 PN_stdfloat BulletBodyNode::
257 get_friction()
const {
260 return get_object()->getFriction();
266 void BulletBodyNode::
267 set_friction(PN_stdfloat friction) {
270 return get_object()->setFriction(friction);
273 #if BT_BULLET_VERSION >= 281 277 PN_stdfloat BulletBodyNode::
278 get_rolling_friction()
const {
281 return get_object()->getRollingFriction();
287 void BulletBodyNode::
288 set_rolling_friction(PN_stdfloat friction) {
291 return get_object()->setRollingFriction(friction);
298 bool BulletBodyNode::
299 has_anisotropic_friction()
const {
302 return get_object()->hasAnisotropicFriction();
309 get_num_shapes()
const {
312 return _shapes.size();
319 get_shape(
int idx)
const {
322 nassertr(idx >= 0 && idx < (
int)_shapes.size(),
nullptr);
329 void BulletBodyNode::
333 do_add_shape(bullet_shape, ts);
339 void BulletBodyNode::
342 nassertv(get_object());
345 btCollisionShape *shape = bullet_shape->ptr();
346 nassertv(shape !=
nullptr);
348 nassertv(!(shape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE &&
349 ((btConvexHullShape *)shape)->getNumVertices() == 0));
352 btTransform trans = TransformState_to_btTrans(ts);
361 btCollisionShape *previous = get_object()->getCollisionShape();
362 btCollisionShape *next;
364 if (_shapes.size() == 0) {
365 nassertv(previous->getShapeType() == EMPTY_SHAPE_PROXYTYPE);
376 next =
new btCompoundShape();
377 ((btCompoundShape *)next)->addChildShape(trans, shape);
380 get_object()->setCollisionShape(next);
385 else if (_shapes.size() == 1) {
386 if (previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
392 ((btCompoundShape *)next)->addChildShape(trans, shape);
397 next =
new btCompoundShape();
399 btTransform previous_trans = btTransform::getIdentity();
400 ((btCompoundShape *)next)->addChildShape(previous_trans, previous);
401 ((btCompoundShape *)next)->addChildShape(trans, shape);
403 get_object()->setCollisionShape(next);
411 nassertv(previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE);
414 ((btCompoundShape *)next)->addChildShape(trans, shape);
417 _shapes.push_back(bullet_shape);
428 void BulletBodyNode::
432 nassertv(get_object());
434 BulletShapes::iterator found;
436 found = find(_shapes.begin(), _shapes.end(), ptshape);
438 if (found == _shapes.end()) {
439 bullet_cat.warning() <<
"shape not attached" << std::endl;
442 _shapes.erase(found);
445 btCollisionShape *previous = get_object()->getCollisionShape();
446 btCollisionShape *next;
448 if (_shapes.size() == 0) {
450 next =
new btEmptyShape();
452 get_object()->setCollisionShape(next);
456 if (previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
460 else if (_shapes.size() == 1) {
462 nassertv(previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
464 btCompoundShape *compound = (btCompoundShape *)previous;
465 compound->removeChildShape(shape->ptr());
467 nassertv(compound->getNumChildShapes() == 1);
471 btTransform trans = compound->getChildTransform(0);
472 if (is_identity(trans)) {
473 next = compound->getChildShape(0);
475 get_object()->setCollisionShape(next);
483 nassertv(previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
485 btCompoundShape *compound = (btCompoundShape *)previous;
486 compound->removeChildShape(shape->ptr());
496 bool BulletBodyNode::
497 is_identity(btTransform &trans) {
499 btVector3
null(0, 0, 0);
501 return (trans.getOrigin() ==
null 502 && trans.getRotation().getAxis() ==
null);
508 LPoint3 BulletBodyNode::
509 get_shape_pos(
int idx)
const {
512 nassertr(idx >= 0 && idx < (
int)_shapes.size(), LPoint3::zero());
514 btCollisionShape *root = get_object()->getCollisionShape();
515 if (root->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
516 btCompoundShape *compound = (btCompoundShape *)root;
518 btTransform trans = compound->getChildTransform(idx);
519 return btVector3_to_LVector3(trans.getOrigin());
522 return LPoint3::zero();
528 LMatrix4 BulletBodyNode::
529 get_shape_mat(
int idx)
const {
532 return do_get_shape_transform(idx)->get_mat();
539 do_get_shape_transform(
int idx)
const {
541 nassertr(idx >= 0 && idx < (
int)_shapes.size(), TransformState::make_identity());
543 btCollisionShape *root = get_object()->getCollisionShape();
544 if (root->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
545 btCompoundShape *compound = (btCompoundShape *)root;
547 btTransform trans = compound->getChildTransform(idx);
548 return btTrans_to_TransformState(trans);
564 return TransformState::make_identity();
571 get_shape_transform(
int idx)
const {
574 return do_get_shape_transform(idx);
584 void BulletBodyNode::
592 void BulletBodyNode::
593 set_deactivation_time(PN_stdfloat dt) {
596 get_object()->setDeactivationTime(dt);
602 PN_stdfloat BulletBodyNode::
603 get_deactivation_time()
const {
606 return get_object()->getDeactivationTime();
612 bool BulletBodyNode::
616 return get_object()->isActive();
622 void BulletBodyNode::
623 set_active(
bool active,
bool force) {
627 get_object()->activate(force);
631 get_object()->forceActivationState(ISLAND_SLEEPING);
634 get_object()->setActivationState(ISLAND_SLEEPING);
642 void BulletBodyNode::
643 force_active(
bool active) {
645 set_active(active,
true);
658 bool is_enabled = get_object()->getActivationState() != DISABLE_DEACTIVATION;
659 if (enabled != is_enabled) {
663 int state = (enabled) ? ACTIVE_TAG : DISABLE_DEACTIVATION;
664 get_object()->forceActivationState(state);
671 bool BulletBodyNode::
672 is_deactivation_enabled()
const {
675 return (get_object()->getActivationState() != DISABLE_DEACTIVATION);
681 bool BulletBodyNode::
685 btCollisionObject *obj = BulletWorld::get_collision_object(node);
688 return get_object()->checkCollideWith(obj);
698 LVecBase3 BulletBodyNode::
699 get_anisotropic_friction()
const {
702 return btVector3_to_LVecBase3(get_object()->getAnisotropicFriction());
708 void BulletBodyNode::
709 set_anisotropic_friction(
const LVecBase3 &friction) {
712 nassertv(!friction.is_nan());
713 get_object()->setAnisotropicFriction(LVecBase3_to_btVector3(friction));
719 bool BulletBodyNode::
720 has_contact_response()
const {
723 return get_object()->hasContactResponse();
729 PN_stdfloat BulletBodyNode::
730 get_contact_processing_threshold()
const {
733 return get_object()->getContactProcessingThreshold();
744 get_object()->setContactProcessingThreshold(threshold);
750 PN_stdfloat BulletBodyNode::
751 get_ccd_swept_sphere_radius()
const {
754 return get_object()->getCcdSweptSphereRadius();
760 void BulletBodyNode::
761 set_ccd_swept_sphere_radius(PN_stdfloat radius) {
764 return get_object()->setCcdSweptSphereRadius(radius);
770 PN_stdfloat BulletBodyNode::
771 get_ccd_motion_threshold()
const {
774 return get_object()->getCcdMotionThreshold();
780 void BulletBodyNode::
781 set_ccd_motion_threshold(PN_stdfloat threshold) {
784 return get_object()->setCcdMotionThreshold(threshold);
790 void BulletBodyNode::
796 for (
size_t j = 0; j < cnode->get_num_solids(); ++j) {
801 if (CollisionSphere::get_class_type() == type) {
803 CPT(
TransformState) ts = TransformState::make_pos(sphere->get_center());
805 do_add_shape(BulletSphereShape::make_from_solid(sphere), ts);
809 else if (CollisionBox::get_class_type() == type) {
811 CPT(
TransformState) ts = TransformState::make_pos(box->get_center());
813 do_add_shape(BulletBoxShape::make_from_solid(box), ts);
817 else if (CollisionCapsule::get_class_type() == type) {
819 CPT(
TransformState) ts = TransformState::make_pos((capsule->get_point_b() + capsule->get_point_a()) / 2.0);
825 else if (CollisionPlane::get_class_type() == type) {
828 do_add_shape(BulletPlaneShape::make_from_solid(plane));
832 else if (CollisionPolygon::get_class_type() == type) {
839 for (
size_t i = 2; i < polygon->get_num_points(); ++i) {
840 LPoint3 p1 = polygon->get_point(0);
841 LPoint3 p2 = polygon->get_point(i - 1);
842 LPoint3 p3 = polygon->get_point(i);
844 mesh->do_add_triangle(p1, p2, p3,
true);
849 if (mesh && mesh->do_get_num_triangles() > 0) {
869 get_shape_bounds()
const {
887 _shape->getBoundingSphere(center, radius);
890 BoundingSphere bounds(btVector3_to_LPoint3(center), (PN_stdfloat)radius);
906 dg.
add_bool(get_collision_response());
910 dg.
add_bool(is_deactivation_enabled());
914 #if BT_BULLET_VERSION >= 281 919 if (has_anisotropic_friction()) {
921 get_anisotropic_friction().write_datagram(dg);
928 for (
unsigned int i = 0; i < _shapes.size(); ++i) {
947 while (shape !=
nullptr) {
949 add_shape(shape, trans);
973 void BulletBodyNode::
975 PandaNode::fillin(scan, manager);
980 set_collision_response(scan.
get_bool());
987 #if BT_BULLET_VERSION >= 281 994 friction.read_datagram(scan);
995 set_anisotropic_friction(friction);
A basic node of the scene graph or data graph.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_transform_dirty()
This method enforces an update of the Bullet transform, that is copies the scene graph transform to t...
bool get_bool()
Extracts a boolean value.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
virtual bool require_fully_complete() const
Some objects require all of their nested pointers to have been completed before the objects themselve...
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
static BitMask< WType, nbits > all_on()
Returns a BitMask whose bits are all on.
The abstract base class for all things that can collide with other things in the world,...
set_contact_processing_threshold
The constraint solver can discard solving contacts, if the distance is above this threshold.
virtual bool safe_to_flatten_below() const
Returns true if a flatten operation may safely continue past this node, or false if nodes below this ...
This defines a bounding sphere, consisting of a center and a radius.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
A cuboid collision volume or object.
void set_scale(PN_stdfloat scale)
Sets the scale component of the transform, leaving translation and rotation untouched.
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
A spherical collision volume or object.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static NodePath any_path(PandaNode *node, Thread *current_thread=Thread::get_current_thread())
Returns a new NodePath that represents any arbitrary path from the root to the indicated node.
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool safe_to_modify_transform() const
Returns true if it is safe to automatically adjust the transform on this kind of node.
void add_bool(bool value)
Adds a boolean value to the datagram.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
Similar to MutexHolder, but for a light mutex.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool safe_to_flatten() const
Returns true if it is generally safe to flatten out this particular kind of Node by duplicating insta...
This implements a solid consisting of a cylinder with hemispherical endcaps, also known as a capsule ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_into_collide_mask
Sets the "into" CollideMask.
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
virtual CollideMask get_legal_collide_mask() const
Returns the subset of CollideMask bits that may be set for this particular type of PandaNode.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node in the scene graph that can hold any number of CollisionSolids.
LVecBase3 get_scale() const
Retrieves the scale component of the transform.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool safe_to_transform() const
Returns true if it is generally safe to transform this particular kind of Node by calling the xform()...
static BulletCapsuleShape * make_from_solid(const CollisionCapsule *solid)
Constructs a new BulletCapsuleShape using the information from a CollisionCapsule from the builtin co...
A class to retrieve the individual data elements previously stored in a Datagram.
TypeHandle is the identifier used to differentiate C++ class types.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
CPT(TransformState) BulletBodyNode
Hook which will be called whenever the total shape of a body changed.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
set_deactivation_enabled
If true, this object will be deactivated after a certain amount of time has passed without movement.
virtual bool safe_to_combine() const
Returns true if it is generally safe to combine this particular kind of PandaNode with other kinds of...
virtual bool safe_to_combine_children() const
Returns true if it is generally safe to combine the children of this PandaNode with each other.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.