189 lines
5.4 KiB
C++
189 lines
5.4 KiB
C++
/**
|
|
* 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 odeWorld.cxx
|
|
* @author joswilso
|
|
* @date 2006-12-27
|
|
*/
|
|
|
|
#include "config_ode.h"
|
|
#include "odeWorld.h"
|
|
#include "odeBody.h"
|
|
|
|
TypeHandle OdeWorld::_type_handle;
|
|
|
|
OdeWorld::
|
|
OdeWorld() :
|
|
_id(dWorldCreate()) {
|
|
if (odeworld_cat.is_debug()) {
|
|
odeworld_cat.debug() << "OdeWorld(" << _id << ")" << "\n";
|
|
}
|
|
_num_surfaces = 0;
|
|
|
|
}
|
|
|
|
OdeWorld::
|
|
OdeWorld(const OdeWorld ©) :
|
|
_id(copy._id) {
|
|
_num_surfaces = 0;
|
|
|
|
}
|
|
|
|
OdeWorld::
|
|
~OdeWorld() {
|
|
if (odeworld_cat.is_debug()) {
|
|
odeworld_cat.debug() << "~OdeWorld(" << _id << ")" << "\n";
|
|
}
|
|
}
|
|
|
|
void OdeWorld::
|
|
destroy() {
|
|
if(_num_surfaces > 0) {
|
|
delete _surface_table;
|
|
}
|
|
nassertv(_id);
|
|
dWorldDestroy(_id);
|
|
}
|
|
|
|
/*
|
|
void OdeWorld::
|
|
assign_surface_body(OdeBody& body, int surface) {
|
|
// odeworld_cat.debug() << "assign_surface_body body.Id =" << body.get_id()
|
|
// << " surface=" << surface << "\n";
|
|
_body_dampen_map[body.get_id()].surfaceType = surface;
|
|
_body_dampen_map[body.get_id()].dampen = 0.0f;
|
|
}
|
|
*/
|
|
|
|
void OdeWorld::
|
|
add_body_dampening(OdeBody& body, int surface) {
|
|
_body_dampen_map[body.get_id()].dampen = 0.0f;
|
|
}
|
|
|
|
|
|
void OdeWorld::
|
|
init_surface_table(uint8_t num_surfaces) {
|
|
_surface_table = new sSurfaceParams[num_surfaces * num_surfaces];
|
|
// _dampen_table = new sSurfaceParams[num_surfaces * num_surfaces];
|
|
_num_surfaces = num_surfaces;
|
|
}
|
|
|
|
void OdeWorld::
|
|
set_surface(int pos1, int pos2, sSurfaceParams& entry) {
|
|
if (odeworld_cat.is_debug()) {
|
|
odeworld_cat.debug() << " pos1 " << pos1 << " pos2 " << pos2 << " num surfaces " << (int)_num_surfaces << " endline\n";
|
|
}
|
|
if((_num_surfaces <= pos1) || (_num_surfaces <= pos2)) {
|
|
odeworld_cat.error() << "surface position exceeds size of surface table, set num_surface in initSurfaceTable higher." << "\n";
|
|
return;
|
|
}
|
|
int true_pos = (pos1 * _num_surfaces) + pos2;
|
|
_surface_table[true_pos].colparams.mode = entry.colparams.mode;
|
|
_surface_table[true_pos].colparams.mu = entry.colparams.mu;
|
|
_surface_table[true_pos].colparams.mu2 = entry.colparams.mu2;
|
|
_surface_table[true_pos].colparams.bounce = entry.colparams.bounce;
|
|
_surface_table[true_pos].colparams.bounce_vel = entry.colparams.bounce_vel;
|
|
_surface_table[true_pos].colparams.soft_cfm = entry.colparams.soft_cfm;
|
|
_surface_table[true_pos].colparams.motion1 = entry.colparams.motion1;
|
|
_surface_table[true_pos].colparams.motion2 = entry.colparams.motion2;
|
|
_surface_table[true_pos].colparams.slip1 = entry.colparams.slip1;
|
|
_surface_table[true_pos].colparams.slip2 = entry.colparams.slip2;
|
|
_surface_table[true_pos].dampen = entry.dampen;
|
|
}
|
|
|
|
|
|
sSurfaceParams& OdeWorld::
|
|
get_surface(uint8_t surface1, uint8_t surface2) {
|
|
int true_pos = 0;
|
|
if(surface1 >= surface2) {
|
|
true_pos = (surface1 * _num_surfaces) + surface2;
|
|
} else {
|
|
true_pos = (surface2 * _num_surfaces) + surface1;
|
|
}
|
|
if((_num_surfaces <= surface1) || (_num_surfaces <= surface2)) {
|
|
odeworld_cat.error() << "surface position exceeds size of surface table, set num_surface in initSurfaceTable higher." << "\n";
|
|
// nassertr_always((_num_surfaces > surface1 && _num_surfaces > surface2),
|
|
// _surface_table[true_pos]);
|
|
}
|
|
return _surface_table[true_pos];
|
|
}
|
|
|
|
void OdeWorld::
|
|
set_surface_entry(uint8_t pos1, uint8_t pos2,
|
|
dReal mu,
|
|
dReal bounce,
|
|
dReal bounce_vel,
|
|
dReal soft_erp,
|
|
dReal soft_cfm,
|
|
dReal slip,
|
|
dReal dampen) {
|
|
// todo: add mode
|
|
sSurfaceParams new_params;
|
|
int someMode = 0;
|
|
if (bounce > 0.0001) {
|
|
someMode |= dContactBounce;
|
|
}
|
|
if (soft_erp > 0.0001) {
|
|
someMode |= dContactSoftERP;
|
|
}
|
|
if (soft_cfm > 0.0001) {
|
|
someMode |= dContactSoftCFM;
|
|
}
|
|
if (slip > 0.0001) {
|
|
someMode = someMode | dContactSlip1 | dContactSlip2;
|
|
}
|
|
new_params.colparams.mode = dContactBounce | dContactSoftCFM | dContactApprox1;// | dContactSoftERP;
|
|
new_params.colparams.mu = mu;
|
|
new_params.colparams.mu2 = mu;
|
|
new_params.colparams.bounce = bounce;
|
|
new_params.colparams.bounce_vel = bounce_vel;
|
|
new_params.colparams.soft_erp = soft_erp;
|
|
new_params.colparams.soft_cfm = soft_cfm;
|
|
new_params.colparams.slip1 = slip;
|
|
new_params.colparams.slip2 = slip;
|
|
new_params.colparams.motion1 = 0.0;
|
|
new_params.colparams.motion2 = 0.0;
|
|
new_params.dampen = dampen;
|
|
// todo: a bit of wasted space here
|
|
set_surface(pos1, pos2, new_params);
|
|
|
|
if(pos1 >= pos2) {
|
|
set_surface(pos1, pos2, new_params);
|
|
} else {
|
|
set_surface(pos2, pos1, new_params);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void OdeWorld::
|
|
set_dampen_on_bodies(dBodyID id1, dBodyID id2,dReal damp) {
|
|
if(_body_dampen_map[id1].dampen < damp) {
|
|
_body_dampen_map[id1].dampen = damp;
|
|
}
|
|
if(_body_dampen_map[id2].dampen < damp) {
|
|
_body_dampen_map[id2].dampen = damp;
|
|
}
|
|
}
|
|
|
|
float OdeWorld::
|
|
apply_dampening(float dt, OdeBody& body) {
|
|
dBodyID bodyId = body.get_id();
|
|
dReal damp = _body_dampen_map[bodyId].dampen;
|
|
float dampening = 1.00 - (damp * dt);
|
|
body.set_angular_vel(body.get_angular_vel() * dampening);
|
|
body.set_linear_vel(body.get_linear_vel() * dampening);
|
|
_body_dampen_map[bodyId].dampen = 0.0;
|
|
return dampening;
|
|
}
|
|
|
|
OdeWorld::
|
|
operator bool () const {
|
|
return (_id != nullptr);
|
|
}
|