00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "cDistributedSmoothNodeBase.h"
00016 #include "cConnectionRepository.h"
00017 #include "dcField.h"
00018 #include "dcClass.h"
00019 #include "dcmsgtypes.h"
00020 #include "config_distributed.h"
00021
00022 static const PN_stdfloat smooth_node_epsilon = 0.01;
00023 static const double network_time_precision = 100.0;
00024
00025
00026
00027
00028
00029
00030 CDistributedSmoothNodeBase::
00031 CDistributedSmoothNodeBase() {
00032 _repository = NULL;
00033 _is_ai = false;
00034 _ai_id = 0;
00035
00036 #ifdef HAVE_PYTHON
00037 _clock_delta = NULL;
00038 #endif
00039
00040 _currL[0] = 0;
00041 _currL[1] = 0;
00042 }
00043
00044
00045
00046
00047
00048
00049 CDistributedSmoothNodeBase::
00050 ~CDistributedSmoothNodeBase() {
00051 }
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 void CDistributedSmoothNodeBase::
00063 initialize(const NodePath &node_path, DCClass *dclass, CHANNEL_TYPE do_id) {
00064 _node_path = node_path;
00065 _dclass = dclass;
00066 _do_id = do_id;
00067
00068 nassertv(!_node_path.is_empty());
00069
00070 _store_xyz = _node_path.get_pos();
00071 _store_hpr = _node_path.get_hpr();
00072 _store_stop = false;
00073 }
00074
00075
00076
00077
00078
00079
00080 void CDistributedSmoothNodeBase::
00081 send_everything() {
00082 _currL[0] = _currL[1];
00083 d_setSmPosHprL(_store_xyz[0], _store_xyz[1], _store_xyz[2],
00084 _store_hpr[0], _store_hpr[1], _store_hpr[2], _currL[0]);
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 void CDistributedSmoothNodeBase::
00095 broadcast_pos_hpr_full() {
00096 LPoint3 xyz = _node_path.get_pos();
00097 LVecBase3 hpr = _node_path.get_hpr();
00098
00099 int flags = 0;
00100
00101 if (!IS_THRESHOLD_EQUAL(_store_xyz[0], xyz[0], smooth_node_epsilon)) {
00102 _store_xyz[0] = xyz[0];
00103 flags |= F_new_x;
00104 }
00105
00106 if (!IS_THRESHOLD_EQUAL(_store_xyz[1], xyz[1], smooth_node_epsilon)) {
00107 _store_xyz[1] = xyz[1];
00108 flags |= F_new_y;
00109 }
00110
00111 if (!IS_THRESHOLD_EQUAL(_store_xyz[2], xyz[2], smooth_node_epsilon)) {
00112 _store_xyz[2] = xyz[2];
00113 flags |= F_new_z;
00114 }
00115
00116 if (!IS_THRESHOLD_EQUAL(_store_hpr[0], hpr[0], smooth_node_epsilon)) {
00117 _store_hpr[0] = hpr[0];
00118 flags |= F_new_h;
00119 }
00120
00121 if (!IS_THRESHOLD_EQUAL(_store_hpr[1], hpr[1], smooth_node_epsilon)) {
00122 _store_hpr[1] = hpr[1];
00123 flags |= F_new_p;
00124 }
00125
00126 if (!IS_THRESHOLD_EQUAL(_store_hpr[2], hpr[2], smooth_node_epsilon)) {
00127 _store_hpr[2] = hpr[2];
00128 flags |= F_new_r;
00129 }
00130
00131 if (_currL[0] != _currL[1]) {
00132
00133
00134 _currL[0] = _currL[1];
00135
00136 _store_stop = false;
00137 d_setSmPosHprL(_store_xyz[0], _store_xyz[1], _store_xyz[2],
00138 _store_hpr[0], _store_hpr[1], _store_hpr[2], _currL[0]);
00139
00140 } else if (flags == 0) {
00141
00142 if (!_store_stop) {
00143 _store_stop = true;
00144 d_setSmStop();
00145 }
00146
00147 } else if (only_changed(flags, F_new_h)) {
00148
00149 _store_stop = false;
00150 d_setSmH(_store_hpr[0]);
00151
00152 } else if (only_changed(flags, F_new_z)) {
00153
00154 _store_stop = false;
00155 d_setSmZ(_store_xyz[2]);
00156
00157 } else if (only_changed(flags, F_new_x | F_new_y)) {
00158
00159 _store_stop = false;
00160 d_setSmXY(_store_xyz[0], _store_xyz[1]);
00161
00162 } else if (only_changed(flags, F_new_x | F_new_z)) {
00163
00164 _store_stop = false;
00165 d_setSmXZ(_store_xyz[0], _store_xyz[2]);
00166
00167 } else if (only_changed(flags, F_new_x | F_new_y | F_new_z)) {
00168
00169 _store_stop = false;
00170 d_setSmPos(_store_xyz[0], _store_xyz[1], _store_xyz[2]);
00171
00172 } else if (only_changed(flags, F_new_h | F_new_p | F_new_r)) {
00173
00174 _store_stop = false;
00175 d_setSmHpr(_store_hpr[0], _store_hpr[1], _store_hpr[2]);
00176
00177 } else if (only_changed(flags, F_new_x | F_new_y | F_new_h)) {
00178
00179 _store_stop = false;
00180 d_setSmXYH(_store_xyz[0], _store_xyz[1], _store_hpr[0]);
00181
00182 } else if (only_changed(flags, F_new_x | F_new_y | F_new_z | F_new_h)) {
00183
00184 _store_stop = false;
00185 d_setSmXYZH(_store_xyz[0], _store_xyz[1], _store_xyz[2], _store_hpr[0]);
00186
00187 } else {
00188
00189 _store_stop = false;
00190 d_setSmPosHpr(_store_xyz[0], _store_xyz[1], _store_xyz[2],
00191 _store_hpr[0], _store_hpr[1], _store_hpr[2]);
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 void CDistributedSmoothNodeBase::
00202 broadcast_pos_hpr_xyh() {
00203 LPoint3 xyz = _node_path.get_pos();
00204 LVecBase3 hpr = _node_path.get_hpr();
00205
00206 int flags = 0;
00207
00208 if (!IS_THRESHOLD_EQUAL(_store_xyz[0], xyz[0], smooth_node_epsilon)) {
00209 _store_xyz[0] = xyz[0];
00210 flags |= F_new_x;
00211 }
00212
00213 if (!IS_THRESHOLD_EQUAL(_store_xyz[1], xyz[1], smooth_node_epsilon)) {
00214 _store_xyz[1] = xyz[1];
00215 flags |= F_new_y;
00216 }
00217
00218 if (!IS_THRESHOLD_EQUAL(_store_hpr[0], hpr[0], smooth_node_epsilon)) {
00219 _store_hpr[0] = hpr[0];
00220 flags |= F_new_h;
00221 }
00222
00223 if (flags == 0) {
00224
00225 if (!_store_stop) {
00226 _store_stop = true;
00227 d_setSmStop();
00228 }
00229
00230 } else if (only_changed(flags, F_new_h)) {
00231
00232 _store_stop = false;
00233 d_setSmH(_store_hpr[0]);
00234
00235 } else if (only_changed(flags, F_new_x | F_new_y)) {
00236
00237 _store_stop = false;
00238 d_setSmXY(_store_xyz[0], _store_xyz[1]);
00239
00240 } else {
00241
00242 _store_stop = false;
00243 d_setSmXYH(_store_xyz[0], _store_xyz[1], _store_hpr[0]);
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 void CDistributedSmoothNodeBase::
00254 broadcast_pos_hpr_xy() {
00255 LPoint3 xyz = _node_path.get_pos();
00256
00257 int flags = 0;
00258
00259 if (!IS_THRESHOLD_EQUAL(_store_xyz[0], xyz[0], smooth_node_epsilon)) {
00260 _store_xyz[0] = xyz[0];
00261 flags |= F_new_x;
00262 }
00263
00264 if (!IS_THRESHOLD_EQUAL(_store_xyz[1], xyz[1], smooth_node_epsilon)) {
00265 _store_xyz[1] = xyz[1];
00266 flags |= F_new_y;
00267 }
00268
00269 if (flags == 0) {
00270
00271 if (!_store_stop) {
00272 _store_stop = true;
00273 d_setSmStop();
00274 }
00275
00276 } else {
00277
00278 _store_stop = false;
00279 d_setSmXY(_store_xyz[0], _store_xyz[1]);
00280 }
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290 void CDistributedSmoothNodeBase::
00291 begin_send_update(DCPacker &packer, const string &field_name) {
00292 DCField *field = _dclass->get_field_by_name(field_name);
00293 nassertv(field != (DCField *)NULL);
00294
00295 if (_is_ai) {
00296
00297 packer.raw_pack_uint8(1);
00298 packer.RAW_PACK_CHANNEL(_do_id);
00299 packer.RAW_PACK_CHANNEL(_ai_id);
00300
00301 packer.raw_pack_uint16(STATESERVER_OBJECT_UPDATE_FIELD);
00302 packer.raw_pack_uint32(_do_id);
00303 packer.raw_pack_uint16(field->get_number());
00304
00305 } else {
00306 packer.raw_pack_uint16(CLIENT_OBJECT_UPDATE_FIELD);
00307 packer.raw_pack_uint32(_do_id);
00308 packer.raw_pack_uint16(field->get_number());
00309 }
00310
00311 packer.begin_pack(field);
00312 packer.push();
00313 }
00314
00315
00316
00317
00318
00319
00320 void CDistributedSmoothNodeBase::
00321 finish_send_update(DCPacker &packer) {
00322 #ifdef HAVE_PYTHON
00323 nassertv(_clock_delta != NULL);
00324 PyObject *clock_delta = PyObject_GetAttrString(_clock_delta, "delta");
00325 nassertv(clock_delta != NULL);
00326 double delta = PyFloat_AsDouble(clock_delta);
00327 Py_DECREF(clock_delta);
00328 #else
00329 static const double delta = 0.0f;
00330 #endif // HAVE_PYTHON
00331
00332 double local_time = ClockObject::get_global_clock()->get_real_time();
00333
00334 int network_time = (int)cfloor(((local_time - delta) * network_time_precision) + 0.5);
00335
00336
00337 network_time = ((network_time + 0x8000) & 0xFFFF) - 0x8000;
00338 packer.pack_int(network_time);
00339
00340 packer.pop();
00341 bool pack_ok = packer.end_pack();
00342 if (pack_ok) {
00343 Datagram dg(packer.get_data(), packer.get_length());
00344 nassertv(_repository != NULL);
00345 _repository->send_datagram(dg);
00346
00347 } else {
00348 #ifndef NDEBUG
00349 if (packer.had_range_error()) {
00350 ostringstream error;
00351 error << "Node position out of range for DC file: "
00352 << _node_path << " pos = " << _store_xyz
00353 << " hpr = " << _store_hpr
00354 << " zoneId = " << _currL[0];
00355
00356 #ifdef HAVE_PYTHON
00357 string message = error.str();
00358 distributed_cat.warning()
00359 << message << "\n";
00360 PyErr_SetString(PyExc_ValueError, message.c_str());
00361 #else
00362 nassert_raise(error.str());
00363 #endif
00364
00365 } else {
00366 const char *message = "Unexpected pack error in DC file.";
00367 #ifdef HAVE_PYTHON
00368 distributed_cat.warning()
00369 << message << "\n";
00370 PyErr_SetString(PyExc_TypeError, message);
00371 #else
00372 nassert_raise(message);
00373 #endif
00374 }
00375 #endif
00376 }
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 void CDistributedSmoothNodeBase::
00388 set_curr_l(PN_uint64 l) {
00389 _currL[1] = l;
00390 }
00391
00392 void CDistributedSmoothNodeBase::
00393 print_curr_l() {
00394 cout << "printCurrL: sent l: " << _currL[1] << " last set l: " << _currL[0] << "\n";
00395 }
00396