/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * * All use of this software is subject to the terms of the revised BSD * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * * @file bulletSoftBodyNode.h * @author enn0x * @date 2010-12-27 */ #ifndef __BULLET_SOFT_BODY_NODE_H__ #define __BULLET_SOFT_BODY_NODE_H__ #include "pandabase.h" #include "bullet_includes.h" #include "bullet_utils.h" #include "bulletBodyNode.h" #include "collideMask.h" #include "geom.h" #include "geomNode.h" #include "geomVertexFormat.h" #include "boundingBox.h" #include "nurbsCurveEvaluator.h" #include "nurbsSurfaceEvaluator.h" #include "pta_LVecBase3.h" class BulletRigidBodyNode; class BulletSoftBodyConfig; class BulletSoftBodyControl; class BulletSoftBodyMaterial; class BulletSoftBodyWorldInfo; /** * */ class EXPCL_PANDABULLET BulletSoftBodyNodeElement { PUBLISHED: INLINE ~BulletSoftBodyNodeElement(); INLINE static BulletSoftBodyNodeElement empty(); LPoint3 get_pos() const; LVector3 get_velocity() const; LVector3 get_normal() const; PN_stdfloat get_inv_mass() const; PN_stdfloat get_area() const; int is_attached() const; MAKE_PROPERTY(pos, get_pos); MAKE_PROPERTY(velocity, get_velocity); MAKE_PROPERTY(normal, get_normal); MAKE_PROPERTY(inv_mass, get_inv_mass); MAKE_PROPERTY(area, get_area); MAKE_PROPERTY(attached, is_attached); public: BulletSoftBodyNodeElement(btSoftBody::Node &node); private: btSoftBody::Node &_node; }; /** * */ class EXPCL_PANDABULLET BulletSoftBodyNode : public BulletBodyNode { public: BulletSoftBodyNode(btSoftBody *body, const char *name="softbody"); PUBLISHED: INLINE ~BulletSoftBodyNode(); BulletSoftBodyConfig get_cfg(); BulletSoftBodyWorldInfo get_world_info(); void generate_bending_constraints(int distance, BulletSoftBodyMaterial *material=nullptr); void randomize_constraints(); // Mass, volume, density void set_volume_mass(PN_stdfloat mass); void set_volume_density(PN_stdfloat density); void set_total_mass(PN_stdfloat mass, bool fromfaces=false); void set_total_density(PN_stdfloat density); void set_mass(int node, PN_stdfloat mass); PN_stdfloat get_mass(int node) const; PN_stdfloat get_total_mass() const; PN_stdfloat get_volume() const; // Force void add_force(const LVector3 &force); void add_force(const LVector3 &force, int node); void set_velocity(const LVector3 &velocity); void add_velocity(const LVector3 &velocity); void add_velocity(const LVector3 &velocity, int node); void set_wind_velocity(const LVector3 &velocity); LVector3 get_wind_velocity() const; void set_pose(bool bvolume, bool bframe); BoundingBox get_aabb() const; // Cluster void generate_clusters(int k, int maxiterations=8192); void release_cluster(int index); void release_clusters(); int get_num_clusters() const; LVecBase3 cluster_com(int cluster) const; // Rendering void link_geom(Geom *geom); void unlink_geom(); void link_curve(NurbsCurveEvaluator *curve); void unlink_curve(); void link_surface(NurbsSurfaceEvaluator *surface); void unlink_surface(); // Anchors void append_anchor(int node, BulletRigidBodyNode *body, bool disable=false); void append_anchor(int node, BulletRigidBodyNode *body, const LVector3 &pivot, bool disable=false); // Links void append_linear_joint(BulletBodyNode *body, int cluster, PN_stdfloat erp=1.0, PN_stdfloat cfm=1.0, PN_stdfloat split=1.0); void append_linear_joint(BulletBodyNode *body, const LPoint3 &pos, PN_stdfloat erp=1.0, PN_stdfloat cfm=1.0, PN_stdfloat split=1.0); void append_angular_joint(BulletBodyNode *body, const LVector3 &axis, PN_stdfloat erp=1.0, PN_stdfloat cfm=1.0, PN_stdfloat split=1.0, BulletSoftBodyControl *control=nullptr); // Materials int get_num_materials() const; BulletSoftBodyMaterial get_material(int idx) const; MAKE_SEQ(get_materials, get_num_materials, get_material); BulletSoftBodyMaterial append_material(); // Nodes int get_num_nodes() const; BulletSoftBodyNodeElement get_node(int idx) const; MAKE_SEQ(get_nodes, get_num_nodes, get_node); int get_closest_node_index(LVecBase3 point, bool local); // Factory static PT(BulletSoftBodyNode) make_rope( BulletSoftBodyWorldInfo &info, const LPoint3 &from, const LPoint3 &to, int res, int fixeds); static PT(BulletSoftBodyNode) make_patch( BulletSoftBodyWorldInfo &info, const LPoint3 &corner00, const LPoint3 &corner10, const LPoint3 &corner01, const LPoint3 &corner11, int resx, int resy, int fixeds, bool gendiags); static PT(BulletSoftBodyNode) make_ellipsoid( BulletSoftBodyWorldInfo &info, const LPoint3 ¢er, const LVecBase3 &radius, int res); static PT(BulletSoftBodyNode) make_tri_mesh( BulletSoftBodyWorldInfo &info, const Geom *geom, bool randomizeConstraints=true); static PT(BulletSoftBodyNode) make_tri_mesh( BulletSoftBodyWorldInfo &info, PTA_LVecBase3 points, PTA_int indices, bool randomizeConstraints=true); static PT(BulletSoftBodyNode) make_tet_mesh( BulletSoftBodyWorldInfo &info, PTA_LVecBase3 points, PTA_int indices, bool tetralinks=true); static PT(BulletSoftBodyNode) make_tet_mesh( BulletSoftBodyWorldInfo &info, const char *ele, const char *face, const char *node); MAKE_PROPERTY(cfg, get_cfg); MAKE_PROPERTY(world_info, get_world_info); MAKE_PROPERTY(wind_velocity, get_wind_velocity, set_wind_velocity); MAKE_PROPERTY(aabb, get_aabb); MAKE_PROPERTY(num_clusters, get_num_clusters); MAKE_SEQ_PROPERTY(materials, get_num_materials, get_material); MAKE_SEQ_PROPERTY(nodes, get_num_nodes, get_node); public: virtual btCollisionObject *get_object() const; void do_sync_p2b(); void do_sync_b2p(); protected: virtual void transform_changed(); private: btSoftBody *_soft; CPT(TransformState) _sync; bool _sync_disable; PT(Geom) _geom; PT(NurbsCurveEvaluator) _curve; PT(NurbsSurfaceEvaluator) _surface; static int get_point_index(LVecBase3 p, PTA_LVecBase3 points); static int next_line(const char *buffer); BoundingBox do_get_aabb() const; int do_get_closest_node_index(LVecBase3 point, bool local); public: static TypeHandle get_class_type() { return _type_handle; } static void init_type() { BulletBodyNode::init_type(); register_type(_type_handle, "BulletSoftBodyNode", BulletBodyNode::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); } virtual TypeHandle force_init_type() { init_type(); return get_class_type(); } private: static TypeHandle _type_handle; }; #include "bulletSoftBodyNode.I" #endif // __BULLET_SOFT_BODY_NODE_H__