15 #include "cDistributedSmoothNodeBase.h" 16 #include "cConnectionRepository.h" 19 #include "dcmsgtypes.h" 20 #include "config_distributed.h" 22 static const PN_stdfloat smooth_node_epsilon = 0.01;
23 static const double network_time_precision = 100.0;
30 CDistributedSmoothNodeBase::
31 CDistributedSmoothNodeBase() {
49 CDistributedSmoothNodeBase::
50 ~CDistributedSmoothNodeBase() {
64 _node_path = node_path;
70 _store_xyz = _node_path.
get_pos();
71 _store_hpr = _node_path.
get_hpr();
82 _currL[0] = _currL[1];
83 d_setSmPosHprL(_store_xyz[0], _store_xyz[1], _store_xyz[2],
84 _store_hpr[0], _store_hpr[1], _store_hpr[2], _currL[0]);
101 if (!IS_THRESHOLD_EQUAL(_store_xyz[0], xyz[0], smooth_node_epsilon)) {
102 _store_xyz[0] = xyz[0];
106 if (!IS_THRESHOLD_EQUAL(_store_xyz[1], xyz[1], smooth_node_epsilon)) {
107 _store_xyz[1] = xyz[1];
111 if (!IS_THRESHOLD_EQUAL(_store_xyz[2], xyz[2], smooth_node_epsilon)) {
112 _store_xyz[2] = xyz[2];
116 if (!IS_THRESHOLD_EQUAL(_store_hpr[0], hpr[0], smooth_node_epsilon)) {
117 _store_hpr[0] = hpr[0];
121 if (!IS_THRESHOLD_EQUAL(_store_hpr[1], hpr[1], smooth_node_epsilon)) {
122 _store_hpr[1] = hpr[1];
126 if (!IS_THRESHOLD_EQUAL(_store_hpr[2], hpr[2], smooth_node_epsilon)) {
127 _store_hpr[2] = hpr[2];
131 if (_currL[0] != _currL[1]) {
134 _currL[0] = _currL[1];
137 d_setSmPosHprL(_store_xyz[0], _store_xyz[1], _store_xyz[2],
138 _store_hpr[0], _store_hpr[1], _store_hpr[2], _currL[0]);
140 }
else if (flags == 0) {
147 }
else if (only_changed(flags, F_new_h)) {
150 d_setSmH(_store_hpr[0]);
152 }
else if (only_changed(flags, F_new_z)) {
155 d_setSmZ(_store_xyz[2]);
157 }
else if (only_changed(flags, F_new_x | F_new_y)) {
160 d_setSmXY(_store_xyz[0], _store_xyz[1]);
162 }
else if (only_changed(flags, F_new_x | F_new_z)) {
165 d_setSmXZ(_store_xyz[0], _store_xyz[2]);
167 }
else if (only_changed(flags, F_new_x | F_new_y | F_new_z)) {
170 d_setSmPos(_store_xyz[0], _store_xyz[1], _store_xyz[2]);
172 }
else if (only_changed(flags, F_new_h | F_new_p | F_new_r)) {
175 d_setSmHpr(_store_hpr[0], _store_hpr[1], _store_hpr[2]);
177 }
else if (only_changed(flags, F_new_x | F_new_y | F_new_h)) {
180 d_setSmXYH(_store_xyz[0], _store_xyz[1], _store_hpr[0]);
182 }
else if (only_changed(flags, F_new_x | F_new_y | F_new_z | F_new_h)) {
185 d_setSmXYZH(_store_xyz[0], _store_xyz[1], _store_xyz[2], _store_hpr[0]);
190 d_setSmPosHpr(_store_xyz[0], _store_xyz[1], _store_xyz[2],
191 _store_hpr[0], _store_hpr[1], _store_hpr[2]);
208 if (!IS_THRESHOLD_EQUAL(_store_xyz[0], xyz[0], smooth_node_epsilon)) {
209 _store_xyz[0] = xyz[0];
213 if (!IS_THRESHOLD_EQUAL(_store_xyz[1], xyz[1], smooth_node_epsilon)) {
214 _store_xyz[1] = xyz[1];
218 if (!IS_THRESHOLD_EQUAL(_store_hpr[0], hpr[0], smooth_node_epsilon)) {
219 _store_hpr[0] = hpr[0];
230 }
else if (only_changed(flags, F_new_h)) {
233 d_setSmH(_store_hpr[0]);
235 }
else if (only_changed(flags, F_new_x | F_new_y)) {
238 d_setSmXY(_store_xyz[0], _store_xyz[1]);
243 d_setSmXYH(_store_xyz[0], _store_xyz[1], _store_hpr[0]);
259 if (!IS_THRESHOLD_EQUAL(_store_xyz[0], xyz[0], smooth_node_epsilon)) {
260 _store_xyz[0] = xyz[0];
264 if (!IS_THRESHOLD_EQUAL(_store_xyz[1], xyz[1], smooth_node_epsilon)) {
265 _store_xyz[1] = xyz[1];
279 d_setSmXY(_store_xyz[0], _store_xyz[1]);
290 void CDistributedSmoothNodeBase::
291 begin_send_update(
DCPacker &packer,
const string &field_name) {
293 nassertv(field != (
DCField *)NULL);
298 packer.RAW_PACK_CHANNEL(_do_id);
299 packer.RAW_PACK_CHANNEL(_ai_id);
320 void CDistributedSmoothNodeBase::
321 finish_send_update(
DCPacker &packer) {
323 nassertv(_clock_delta != NULL);
324 PyObject *clock_delta = PyObject_GetAttrString(_clock_delta,
"delta");
325 nassertv(clock_delta != NULL);
326 double delta = PyFloat_AsDouble(clock_delta);
327 Py_DECREF(clock_delta);
329 static const double delta = 0.0f;
330 #endif // HAVE_PYTHON 334 int network_time = (int)cfloor(((local_time - delta) * network_time_precision) + 0.5);
337 network_time = ((network_time + 0x8000) & 0xFFFF) - 0x8000;
344 nassertv(_repository != NULL);
351 error <<
"Node position out of range for DC file: " 352 << _node_path <<
" pos = " << _store_xyz
353 <<
" hpr = " << _store_hpr
354 <<
" zoneId = " << _currL[0];
357 string message = error.str();
358 distributed_cat.warning()
360 PyErr_SetString(PyExc_ValueError, message.c_str());
362 nassert_raise(error.str());
366 const char *message =
"Unexpected pack error in DC file.";
368 distributed_cat.warning()
370 PyErr_SetString(PyExc_TypeError, message);
372 nassert_raise(message);
392 void CDistributedSmoothNodeBase::
394 cout <<
"printCurrL: sent l: " << _currL[1] <<
" last set l: " << _currL[0] <<
"\n";
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
bool had_range_error() const
Returns true if there has been an range validation error since the most recent call to begin(); in pa...
void broadcast_pos_hpr_full()
Examines the complete pos/hpr information to see which of the six elements have changed, and broadcasts the appropriate messages.
This is the base class for all three-component vectors and points.
void pack_int(int value)
Packs the indicated numeric or string value into the stream.
int get_number() const
Returns a unique index number associated with this field.
bool is_empty() const
Returns true if the NodePath contains no nodes.
void broadcast_pos_hpr_xyh()
Examines only X, Y, and H of the pos/hpr information, and broadcasts the appropriate messages...
DCField * get_field_by_name(const string &name) const
Returns a pointer to the DCField that shares the indicated name.
A single field of a Distributed Class, either atomic or molecular.
void raw_pack_uint8(unsigned int value)
Packs the data into the buffer between packing sessions.
void set_curr_l(PN_uint64 l)
Appends the timestamp and sends the update.
bool send_datagram(const Datagram &dg)
Queues the indicated datagram for sending to the server.
Defines a particular DistributedClass as read from an input .dc file.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
size_t get_length() const
Returns the current length of the buffer.
void raw_pack_uint32(unsigned int value)
Packs the data into the buffer between packing sessions.
void raw_pack_uint16(unsigned int value)
Packs the data into the buffer between packing sessions.
void push()
Marks the beginning of a nested series of fields.
double get_real_time() const
Returns the actual number of seconds elapsed since the ClockObject was created, or since it was last ...
const char * get_data() const
Returns the beginning of the data buffer.
LVecBase3 get_hpr() const
Retrieves the rotation component of the transform.
void send_everything()
Broadcasts the current pos/hpr in its complete form.
LPoint3 get_pos() const
Retrieves the translation component of the transform.
void broadcast_pos_hpr_xy()
Examines only X and Y of the pos/hpr information, and broadcasts the appropriate messages.
void begin_pack(const DCPackerInterface *root)
Begins a packing session.
This class can be used for packing a series of numeric and string data into a binary stream...
void initialize(const NodePath &node_path, DCClass *dclass, CHANNEL_TYPE do_id)
Initializes the internal structures from some constructs that are normally stored only in Python...
bool end_pack()
Finishes a packing session.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void pop()
Marks the end of a nested series of fields.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...