Hello,
I ported the Python Softbdy Traingles demo to C++ because I’d like to use it as a basis to create a softbody ball (I’m using a solid in my game at the moment for simplicity). When I run the demo I have two problems - one is that I get an assertion:
Assertion failed: get_num_geoms() == 2 at line 213 of c:\buildslave\dev_sdk_win_
amd64\build\panda3d\panda\src\bullet\bulletDebugNode.cxx
And also no wireframe despite having it enabled. I maye have screwed that up somehow. Code is below and runs in Release x64 for devel.
#include "pandaFramework.h"
#include "windowFramework.h"
#include "nodePath.h"
#include "clockObject.h"
#include "asyncTask.h"
#include "genericAsyncTask.h"
#include "bulletWorld.h"
#include "bulletPlaneShape.h"
#include "bulletBoxShape.h"
#include "bulletSoftBodyWorldInfo.h"
#include "bulletSoftBodyMaterial.h"
#include "bulletSoftBodyConfig.h"
#include "GeomVertexFormat.h"
#include "bulletHelper.h"
BulletWorld *get_physics_world() {
// physics_world is supposed to be an global variable,
// but declaring global variables is not cool
// for good programmers lol, instead, should use static keyword.
static BulletWorld *physics_world = new BulletWorld();
return physics_world;
}
AsyncTask::DoneStatus update_scene(GenericAsyncTask* task, void* data) {
// Get dt (from Python example) and apply to do_physics(float, int, int);
ClockObject *co = ClockObject::get_global_clock();
get_physics_world()->do_physics(co->get_dt(), 10, 1.0 / 180.0);
return AsyncTask::DS_cont;
}
int main(int argc, char *argv[]) {
// All variables.
PandaFramework framework;
PT(WindowFramework) window;
NodePath camera;
PT(AsyncTaskManager) task_mgr;
// Init everything :D
framework.open_framework(argc, argv);
// framework->set_window_title("Bullet Physics");
window = framework.open_window();
window->enable_keyboard();
window->setup_trackball();
camera = window->get_camera_group();
task_mgr = AsyncTaskManager::get_global_ptr();
// Make physics simulation.
// Static world stuff.
get_physics_world()->set_gravity(0, 0, -9.81f);
BulletSoftBodyWorldInfo info = get_physics_world()->get_world_info();
info.set_air_density(1.2);
info.set_water_density(0);
info.set_water_normal(LVector3(0,0,0));
LPoint3 centre = LPoint3(0,0,0);
LVector3 radius = LVector3(1,1,1) * 1.5;
PT(BulletSoftBodyNode) bodyNode = BulletSoftBodyNode::make_ellipsoid(info,centre,radius,128);
bodyNode->set_name("Ellipsoid");
BulletSoftBodyMaterial material = bodyNode->get_material(0);
material.setLinearStiffness(0.1);
bodyNode->get_cfg().set_dynamic_friction_coefficient(1);
bodyNode->get_cfg().set_damping_coefficient(0.001);
bodyNode->get_cfg().set_pressure_coefficient(1500);
bodyNode->set_total_mass(30,true);
bodyNode->set_pose(true,false);
NodePath bodyNP = window->get_render().attach_new_node(bodyNode);
bodyNP.set_pos(15,0,12);
bodyNP.set_h(90.0);
get_physics_world()->attach_soft_body(bodyNode);
static const GeomVertexFormat* fmt = GeomVertexFormat::get_v3n3t2();
PT(Geom) geom = BulletHelper::make_geom_from_faces(bodyNode,fmt,true);
bodyNode->link_geom(geom);
PT(BulletDebugNode) visNode = new BulletDebugNode("EllipsoidVisual");
visNode->add_geom(geom);
NodePath visNP = bodyNP.attach_new_node(visNode);
//visNode = new BulletDebugNode("Debug");
PT(BulletPlaneShape) floor_shape = new BulletPlaneShape(LVecBase3f(0, 0, 1), 1);
PT(BulletRigidBodyNode) floor_rigid_node = new BulletRigidBodyNode("Ground");
floor_rigid_node->add_shape(floor_shape);
NodePath np_ground = window->get_render().attach_new_node(floor_rigid_node);
np_ground.set_pos(0, 0, -2);
get_physics_world()->attach_rigid_body(floor_rigid_node);
visNode->show_bounding_boxes(true);
visNode->show_constraints(true);
visNode->show_normals(true);
visNode->show_wireframe(true);
get_physics_world()->set_debug_node(visNode);
visNP.show();
PT(GenericAsyncTask) task;
task = new GenericAsyncTask("Scene update", &update_scene, (void*) NULL);
task_mgr->add(task);
framework.main_loop();
framework.close_framework();
return (0);
}