00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "config_ode.h"
00016 #include "odeWorld.h"
00017
00018 TypeHandle OdeWorld::_type_handle;
00019
00020 OdeWorld::
00021 OdeWorld() :
00022 _id(dWorldCreate()) {
00023 odeworld_cat.debug() << get_type() << "(" << _id << ")" << "\n";
00024 _num_surfaces = 0;
00025
00026 }
00027
00028 OdeWorld::
00029 OdeWorld(const OdeWorld ©) :
00030 _id(copy._id) {
00031 _num_surfaces = 0;
00032
00033 }
00034
00035 OdeWorld::
00036 ~OdeWorld() {
00037 odeworld_cat.debug() << "~" << get_type() << "(" << _id << ")" << "\n";
00038 }
00039
00040 void OdeWorld::
00041 destroy() {
00042 if(_num_surfaces > 0) {
00043 delete _surface_table;
00044 }
00045 nassertv(_id);
00046 dWorldDestroy(_id);
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 void OdeWorld::
00059 add_body_dampening(OdeBody& body, int surface) {
00060 _body_dampen_map[body.get_id()].dampen = 0.0f;
00061 }
00062
00063
00064 void OdeWorld::
00065 init_surface_table(PN_uint8 num_surfaces) {
00066 _surface_table = new sSurfaceParams[num_surfaces * num_surfaces];
00067
00068 _num_surfaces = num_surfaces;
00069 }
00070
00071 void OdeWorld::
00072 set_surface(int pos1, int pos2, sSurfaceParams& entry) {
00073 odeworld_cat.debug() << " pos1 " << pos1 << " pos2 " << pos2 << " num surfaces " << (int)_num_surfaces << " endline\n";
00074 if((_num_surfaces <= pos1) || (_num_surfaces <= pos2)) {
00075 odeworld_cat.error() << "surface position exceeds size of surface table, set num_surface in initSurfaceTable higher." << "\n";
00076 return;
00077 }
00078 int true_pos = (pos1 * _num_surfaces) + pos2;
00079 _surface_table[true_pos].colparams.mode = entry.colparams.mode;
00080 _surface_table[true_pos].colparams.mu = entry.colparams.mu;
00081 _surface_table[true_pos].colparams.mu2 = entry.colparams.mu2;
00082 _surface_table[true_pos].colparams.bounce = entry.colparams.bounce;
00083 _surface_table[true_pos].colparams.bounce_vel = entry.colparams.bounce_vel;
00084 _surface_table[true_pos].colparams.soft_cfm = entry.colparams.soft_cfm;
00085 _surface_table[true_pos].colparams.motion1 = entry.colparams.motion1;
00086 _surface_table[true_pos].colparams.motion2 = entry.colparams.motion2;
00087 _surface_table[true_pos].colparams.slip1 = entry.colparams.slip1;
00088 _surface_table[true_pos].colparams.slip2 = entry.colparams.slip2;
00089 _surface_table[true_pos].dampen = entry.dampen;
00090 }
00091
00092
00093 sSurfaceParams& OdeWorld::
00094 get_surface(PN_uint8 surface1, PN_uint8 surface2) {
00095 int true_pos = 0;
00096 if(surface1 >= surface2) {
00097 true_pos = (surface1 * _num_surfaces) + surface2;
00098 } else {
00099 true_pos = (surface2 * _num_surfaces) + surface1;
00100 }
00101 if((_num_surfaces <= surface1) || (_num_surfaces <= surface2)) {
00102 odeworld_cat.error() << "surface position exceeds size of surface table, set num_surface in initSurfaceTable higher." << "\n";
00103
00104 }
00105 return _surface_table[true_pos];
00106 }
00107
00108 void OdeWorld::
00109 set_surface_entry(PN_uint8 pos1, PN_uint8 pos2,
00110 dReal mu,
00111 dReal bounce,
00112 dReal bounce_vel,
00113 dReal soft_erp,
00114 dReal soft_cfm,
00115 dReal slip,
00116 dReal dampen) {
00117
00118 sSurfaceParams new_params;
00119 int someMode = 0;
00120 if (bounce > 0.0001) {
00121 someMode |= dContactBounce;
00122 }
00123 if (soft_erp > 0.0001) {
00124 someMode |= dContactSoftERP;
00125 }
00126 if (soft_cfm > 0.0001) {
00127 someMode |= dContactSoftCFM;
00128 }
00129 if (slip > 0.0001) {
00130 someMode = someMode | dContactSlip1 | dContactSlip2;
00131 }
00132 new_params.colparams.mode = dContactBounce | dContactSoftCFM | dContactApprox1;
00133 new_params.colparams.mu = mu;
00134 new_params.colparams.mu2 = mu;
00135 new_params.colparams.bounce = bounce;
00136 new_params.colparams.bounce_vel = bounce_vel;
00137 new_params.colparams.soft_erp = soft_erp;
00138 new_params.colparams.soft_cfm = soft_cfm;
00139 new_params.colparams.slip1 = slip;
00140 new_params.colparams.slip2 = slip;
00141 new_params.colparams.motion1 = 0.0;
00142 new_params.colparams.motion2 = 0.0;
00143 new_params.dampen = dampen;
00144
00145 set_surface(pos1, pos2, new_params);
00146
00147 if(pos1 >= pos2) {
00148 set_surface(pos1, pos2, new_params);
00149 } else {
00150 set_surface(pos2, pos1, new_params);
00151 }
00152 }
00153
00154
00155
00156 void OdeWorld::
00157 set_dampen_on_bodies(dBodyID id1, dBodyID id2,dReal damp) {
00158 if(_body_dampen_map[id1].dampen < damp) {
00159 _body_dampen_map[id1].dampen = damp;
00160 }
00161 if(_body_dampen_map[id2].dampen < damp) {
00162 _body_dampen_map[id2].dampen = damp;
00163 }
00164 }
00165
00166 float OdeWorld::
00167 apply_dampening(float dt, OdeBody& body) {
00168 dBodyID bodyId = body.get_id();
00169 dReal damp = _body_dampen_map[bodyId].dampen;
00170 float dampening = 1.00 - (damp * dt);
00171 body.set_angular_vel(body.get_angular_vel() * dampening);
00172 body.set_linear_vel(body.get_linear_vel() * dampening);
00173 _body_dampen_map[bodyId].dampen = 0.0;
00174 return dampening;
00175 }
00176
00177 OdeWorld::
00178 operator bool () const {
00179 return (_id != NULL);
00180 }