39BulletBodyNode(
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();
162do_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";
178output(std::ostream &out)
const {
188set_collision_flag(
int flag,
bool value) {
191 int flags = get_object()->getCollisionFlags();
200 get_object()->setCollisionFlags(flags);
207get_collision_flag(
int flag)
const {
210 return (get_object()->getCollisionFlags() & flag) ? true :
false;
220 return get_object()->isStaticObject();
227is_kinematic()
const {
230 return get_object()->isKinematicObject();
236PN_stdfloat BulletBodyNode::
237get_restitution()
const {
240 return get_object()->getRestitution();
247set_restitution(PN_stdfloat restitution) {
250 return get_object()->setRestitution(restitution);
256PN_stdfloat BulletBodyNode::
257get_friction()
const {
260 return get_object()->getFriction();
267set_friction(PN_stdfloat friction) {
270 return get_object()->setFriction(friction);
273#if BT_BULLET_VERSION >= 281
277PN_stdfloat BulletBodyNode::
278get_rolling_friction()
const {
281 return get_object()->getRollingFriction();
288set_rolling_friction(PN_stdfloat friction) {
291 return get_object()->setRollingFriction(friction);
299has_anisotropic_friction()
const {
302 return get_object()->hasAnisotropicFriction();
309get_num_shapes()
const {
312 return _shapes.size();
319get_shape(
int idx)
const {
322 nassertr(idx >= 0 && idx < (
int)_shapes.size(),
nullptr);
333 do_add_shape(bullet_shape, ts);
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);
357 bool scale_changed =
false;
358 if (!prev_transform->is_identity() && prev_transform->get_scale() != LVecBase3(1.0, 1.0, 1.0)) {
361 LightMutex &lock = BulletWorld::get_global_lock();
363 set_transform(prev_transform->set_scale(LVecBase3(1.0, 1.0, 1.0)));
365 scale_changed =
true;
369 btCollisionShape *previous = get_object()->getCollisionShape();
370 btCollisionShape *next;
372 if (_shapes.size() == 0) {
373 nassertv(previous->getShapeType() == EMPTY_SHAPE_PROXYTYPE);
384 next =
new btCompoundShape();
385 ((btCompoundShape *)next)->addChildShape(trans, shape);
388 get_object()->setCollisionShape(next);
393 else if (_shapes.size() == 1) {
394 if (previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
400 ((btCompoundShape *)next)->addChildShape(trans, shape);
405 next =
new btCompoundShape();
407 btTransform previous_trans = btTransform::getIdentity();
408 ((btCompoundShape *)next)->addChildShape(previous_trans, previous);
409 ((btCompoundShape *)next)->addChildShape(trans, shape);
411 get_object()->setCollisionShape(next);
419 nassertv(previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE);
422 ((btCompoundShape *)next)->addChildShape(trans, shape);
425 _shapes.push_back(bullet_shape);
429 CPT(
TransformState) transform = get_transform()->set_scale(prev_transform->get_scale());
430 LightMutex &lock = BulletWorld::get_global_lock();
446 nassertv(get_object());
448 BulletShapes::iterator found;
450 found = find(_shapes.begin(), _shapes.end(), ptshape);
452 if (found == _shapes.end()) {
453 bullet_cat.warning() <<
"shape not attached" << std::endl;
456 _shapes.erase(found);
459 btCollisionShape *previous = get_object()->getCollisionShape();
460 btCollisionShape *next;
462 if (_shapes.size() == 0) {
464 next =
new btEmptyShape();
466 get_object()->setCollisionShape(next);
470 if (previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
474 else if (_shapes.size() == 1) {
476 nassertv(previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
478 btCompoundShape *compound = (btCompoundShape *)previous;
479 compound->removeChildShape(shape->ptr());
481 nassertv(compound->getNumChildShapes() == 1);
485 btTransform trans = compound->getChildTransform(0);
486 if (is_identity(trans)) {
487 next = compound->getChildShape(0);
489 get_object()->setCollisionShape(next);
497 nassertv(previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
499 btCompoundShape *compound = (btCompoundShape *)previous;
500 compound->removeChildShape(shape->ptr());
511is_identity(btTransform &trans) {
513 btVector3 null(0, 0, 0);
515 return (trans.getOrigin() == null
516 && trans.getRotation().getAxis() == null);
522LPoint3 BulletBodyNode::
523get_shape_pos(
int idx)
const {
526 nassertr(idx >= 0 && idx < (
int)_shapes.size(), LPoint3::zero());
528 btCollisionShape *root = get_object()->getCollisionShape();
529 if (root->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
530 btCompoundShape *compound = (btCompoundShape *)root;
532 btTransform trans = compound->getChildTransform(idx);
533 return btVector3_to_LVector3(trans.getOrigin());
536 return LPoint3::zero();
542LMatrix4 BulletBodyNode::
543get_shape_mat(
int idx)
const {
546 return do_get_shape_transform(idx)->get_mat();
553do_get_shape_transform(
int idx)
const {
555 nassertr(idx >= 0 && idx < (
int)_shapes.size(), TransformState::make_identity());
557 btCollisionShape *root = get_object()->getCollisionShape();
558 if (root->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
559 btCompoundShape *compound = (btCompoundShape *)root;
561 btTransform trans = compound->getChildTransform(idx);
562 return btTrans_to_TransformState(trans);
578 return TransformState::make_identity();
585get_shape_transform(
int idx)
const {
588 return do_get_shape_transform(idx);
607set_deactivation_time(PN_stdfloat dt) {
610 get_object()->setDeactivationTime(dt);
616PN_stdfloat BulletBodyNode::
617get_deactivation_time()
const {
620 return get_object()->getDeactivationTime();
630 return get_object()->isActive();
637set_active(
bool active,
bool force) {
641 get_object()->activate(force);
645 get_object()->forceActivationState(ISLAND_SLEEPING);
648 get_object()->setActivationState(ISLAND_SLEEPING);
657force_active(
bool active) {
659 set_active(active,
true);
672 bool is_enabled = get_object()->getActivationState() != DISABLE_DEACTIVATION;
673 if (enabled != is_enabled) {
677 int state = (enabled) ? ACTIVE_TAG : DISABLE_DEACTIVATION;
678 get_object()->forceActivationState(state);
686is_deactivation_enabled()
const {
689 return (get_object()->getActivationState() != DISABLE_DEACTIVATION);
699 btCollisionObject *obj = BulletWorld::get_collision_object(node);
702 return get_object()->checkCollideWith(obj);
712LVecBase3 BulletBodyNode::
713get_anisotropic_friction()
const {
716 return btVector3_to_LVecBase3(get_object()->getAnisotropicFriction());
723set_anisotropic_friction(
const LVecBase3 &friction) {
726 nassertv(!friction.is_nan());
727 get_object()->setAnisotropicFriction(LVecBase3_to_btVector3(friction));
734has_contact_response()
const {
737 return get_object()->hasContactResponse();
743PN_stdfloat BulletBodyNode::
744get_contact_processing_threshold()
const {
747 return get_object()->getContactProcessingThreshold();
758 get_object()->setContactProcessingThreshold(threshold);
764PN_stdfloat BulletBodyNode::
765get_ccd_swept_sphere_radius()
const {
768 return get_object()->getCcdSweptSphereRadius();
775set_ccd_swept_sphere_radius(PN_stdfloat radius) {
778 return get_object()->setCcdSweptSphereRadius(radius);
784PN_stdfloat BulletBodyNode::
785get_ccd_motion_threshold()
const {
788 return get_object()->getCcdMotionThreshold();
795set_ccd_motion_threshold(PN_stdfloat threshold) {
798 return get_object()->setCcdMotionThreshold(threshold);
810 for (
size_t j = 0; j < cnode->get_num_solids(); ++j) {
815 if (CollisionSphere::get_class_type() == type) {
817 CPT(
TransformState) ts = TransformState::make_pos(sphere->get_center());
819 do_add_shape(BulletSphereShape::make_from_solid(sphere), ts);
823 else if (CollisionBox::get_class_type() == type) {
825 CPT(
TransformState) ts = TransformState::make_pos(box->get_center());
827 do_add_shape(BulletBoxShape::make_from_solid(box), ts);
831 else if (CollisionCapsule::get_class_type() == type) {
833 CPT(
TransformState) ts = TransformState::make_pos((capsule->get_point_b() + capsule->get_point_a()) / 2.0);
839 else if (CollisionPlane::get_class_type() == type) {
842 do_add_shape(BulletPlaneShape::make_from_solid(plane));
846 else if (CollisionPolygon::get_class_type() == type) {
853 for (
size_t i = 2; i < polygon->get_num_points(); ++i) {
854 LPoint3 p1 = polygon->get_point(0);
855 LPoint3 p2 = polygon->get_point(i - 1);
856 LPoint3 p3 = polygon->get_point(i);
858 mesh->do_add_triangle(p1, p2, p3,
true);
863 if (mesh && mesh->do_get_num_triangles() > 0) {
901 _shape->getBoundingSphere(center, radius);
904 BoundingSphere bounds(btVector3_to_LPoint3(center), (PN_stdfloat)radius);
920 dg.
add_bool(get_collision_response());
924 dg.
add_bool(is_deactivation_enabled());
928#if BT_BULLET_VERSION >= 281
933 if (has_anisotropic_friction()) {
935 get_anisotropic_friction().write_datagram(dg);
942 for (
unsigned int i = 0; i < _shapes.size(); ++i) {
961 while (shape !=
nullptr) {
963 add_shape(shape, trans);
989 PandaNode::fillin(scan, manager);
994 set_collision_response(scan.
get_bool());
1001#if BT_BULLET_VERSION >= 281
1008 friction.read_datagram(scan);
1009 set_anisotropic_friction(friction);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
static BitMask< uint32_t, nbits > all_on()
Returns a BitMask whose bits are all on.
This defines a bounding sphere, consisting of a center and a radius.
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 bool require_fully_complete() const
Some objects require all of their nested pointers to have been completed before the objects themselve...
virtual bool safe_to_flatten() const
Returns true if it is generally safe to flatten out this particular kind of Node by duplicating insta...
void set_transform_dirty()
This method enforces an update of the Bullet transform, that is copies the scene graph transform to t...
virtual bool safe_to_transform() const
Returns true if it is generally safe to transform this particular kind of Node by calling the xform()...
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 ...
get_shape_bounds
Returns the current bounds of all collision shapes owned by this body.
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 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 safe_to_modify_transform() const
Returns true if it is safe to automatically adjust the transform on this kind of node.
set_contact_processing_threshold
The constraint solver can discard solving contacts, if the distance is above this threshold.
virtual CollideMask get_legal_collide_mask() const
Returns the subset of CollideMask bits that may be set for this particular type of PandaNode.
virtual bool safe_to_combine_children() const
Returns true if it is generally safe to combine the children of this PandaNode with each other.
static BulletCapsuleShape * make_from_solid(const CollisionCapsule *solid)
Constructs a new BulletCapsuleShape using the information from a CollisionCapsule from the builtin co...
A cuboid collision volume or object.
This implements a solid consisting of a cylinder with hemispherical endcaps, also known as a capsule ...
A node in the scene graph that can hold any number of CollisionSolids.
The abstract base class for all things that can collide with other things in the world,...
A spherical collision volume or object.
A class to retrieve the individual data elements previously stored in a Datagram.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
bool get_bool()
Extracts a boolean value.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
void add_bool(bool value)
Adds a boolean value to the datagram.
void release() const
Releases the lightMutex.
void acquire() const
Grabs the lightMutex if it is available.
Similar to MutexHolder, but for a light mutex.
This is a standard, non-reentrant mutex, similar to the Mutex class.
A basic node of the scene graph or data graph.
set_transform
Sets the transform that will be applied to this node and below.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
TypeHandle is the identifier used to differentiate C++ class types.
Base class for objects that can be written to and read from Bam files.
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().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.