move setSmPos() etc. into C++

This commit is contained in:
David Rose 2004-09-06 23:32:17 +00:00
parent 2d3afd2dcc
commit 157b9feb5f
7 changed files with 590 additions and 185 deletions

View File

@ -85,6 +85,7 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
self.DistributedSmoothNode_initialized = 1
DistributedNode.DistributedNode.__init__(self, cr)
DistributedSmoothNodeBase.DistributedSmoothNodeBase.__init__(self)
self.cnode.setRepository(cr, 0, 0)
self.smoother = SmoothMover()
self.smoothStarted = 0
@ -308,11 +309,8 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
DistributedNode.DistributedNode.d_setParent(self, parentToken)
self.forceToTruePosition()
xyz = self.getPos()
hpr = self.getHpr()
x=xyz[0]; y=xyz[1]; z=xyz[2]
h=hpr[0]; p=hpr[1]; r=hpr[2]
self.d_setSmPosHpr(x,y,z,h,p,r)
self.cnode.initialize(self, self.dclass, self.doId)
self.cnode.sendEverything()
### Monitor clock sync ###

View File

@ -9,6 +9,8 @@ class DistributedSmoothNodeAI(DistributedNodeAI.DistributedNodeAI,
DistributedNodeAI.DistributedNodeAI.__init__(self, air, name)
DistributedSmoothNodeBase.DistributedSmoothNodeBase.__init__(self)
self.cnode.setRepository(air, 1, air.ourChannel)
def delete(self):
DistributedSmoothNodeBase.DistributedSmoothNodeBase.delete(self)
DistributedNodeAI.DistributedNodeAI.delete(self)

View File

@ -10,46 +10,13 @@ class DistributedSmoothNodeBase:
BroadcastTypes = Enum('FULL, XYH')
def __init__(self):
pass
self.cnode = CDistributedSmoothNodeBase()
self.cnode.setClockDelta(globalClockDelta)
def delete(self):
# make sure our task is gone
self.stopPosHprBroadcast()
### distributed set pos and hpr functions ###
### These functions send the distributed update to set the
### appropriate values on the remote side. These are
### composite fields, with all the likely combinations
### defined; each function maps (via the dc file) to one or
### more component operations on the remote client.
def d_setSmStop(self):
self.sendUpdate("setSmStop", [globalClockDelta.getFrameNetworkTime()])
def d_setSmH(self, h):
self.sendUpdate("setSmH", [h, globalClockDelta.getFrameNetworkTime()])
def d_setSmXY(self, x, y):
self.sendUpdate("setSmXY", [x, y,
globalClockDelta.getFrameNetworkTime()])
def d_setSmXZ(self, x, z):
self.sendUpdate("setSmXZ", [x, z,
globalClockDelta.getFrameNetworkTime()])
def d_setSmPos(self, x, y, z):
self.sendUpdate("setSmPos", [x, y, z,
globalClockDelta.getFrameNetworkTime()])
def d_setSmHpr(self, h, p, r):
self.sendUpdate("setSmHpr", [h, p, r,
globalClockDelta.getFrameNetworkTime()])
def d_setSmXYH(self, x, y, h):
self.sendUpdate("setSmXYH", [x, y, h,
globalClockDelta.getFrameNetworkTime()])
def d_setSmXYZH(self, x, y, z, h):
self.sendUpdate("setSmXYZH", [x, y, z, h,
globalClockDelta.getFrameNetworkTime()])
def d_setSmPosHpr(self, x, y, z, h, p, r):
self.sendUpdate("setSmPosHpr", [x, y, z, h, p, r,
globalClockDelta.getFrameNetworkTime()])
def b_clearSmoothing(self):
self.d_clearSmoothing()
self.clearSmoothing()
@ -68,6 +35,9 @@ class DistributedSmoothNodeBase:
self.d_broadcastPosHpr = None
def startPosHprBroadcast(self, period=.2, stagger=0, type=None):
if self.cnode == None:
self.initializeCnode()
BT = DistributedSmoothNodeBase.BroadcastTypes
if type is None:
type = BT.FULL
@ -75,8 +45,8 @@ class DistributedSmoothNodeBase:
self.broadcastType = type
broadcastFuncs = {
BT.FULL: self.d_broadcastPosHpr_FULL,
BT.XYH: self.d_broadcastPosHpr_XYH,
BT.FULL: self.cnode.broadcastPosHprFull,
BT.XYH: self.cnode.broadcastPosHprXyh,
}
self.d_broadcastPosHpr = broadcastFuncs[self.broadcastType]
@ -84,23 +54,15 @@ class DistributedSmoothNodeBase:
# over 'period' seconds, to spread out task processing over time
# when a large number of SmoothNodes are created simultaneously.
taskName = self.getPosHprBroadcastTaskName()
# Set up telemetry optimization variables
xyz = self.getPos()
hpr = self.getHpr()
self.__storeX = xyz[0]
self.__storeY = xyz[1]
self.__storeZ = xyz[2]
self.__storeH = hpr[0]
self.__storeP = hpr[1]
self.__storeR = hpr[2]
self.__storeStop = 0
self.__epsilon = 0.01
# Set up telemetry optimization variables
self.cnode.initialize(self, self.dclass, self.doId)
self.__broadcastPeriod = period
# Broadcast our initial position
self.b_clearSmoothing()
self.d_setSmPosHpr(self.__storeX, self.__storeY, self.__storeZ,
self.__storeH, self.__storeP, self.__storeR)
self.cnode.sendEverything()
# remove any old tasks
taskMgr.remove(taskName)
# spawn the new task
@ -119,132 +81,3 @@ class DistributedSmoothNodeBase:
taskMgr.doMethodLater(self.__broadcastPeriod,
self.__posHprBroadcast, taskName)
return Task.done
def d_broadcastPosHpr_FULL(self):
# send out the minimal bits to describe our new position
xyz = self.getPos()
hpr = self.getHpr()
if abs(self.__storeX - xyz[0]) > self.__epsilon:
self.__storeX = xyz[0]
newX = 1
else:
newX = 0
if abs(self.__storeY - xyz[1]) > self.__epsilon:
self.__storeY = xyz[1]
newY = 1
else:
newY = 0
if abs(self.__storeZ - xyz[2]) > self.__epsilon:
self.__storeZ = xyz[2]
newZ = 1
else:
newZ = 0
if abs(self.__storeH - hpr[0]) > self.__epsilon:
self.__storeH = hpr[0]
newH = 1
else:
newH = 0
if abs(self.__storeP - hpr[1]) > self.__epsilon:
self.__storeP = hpr[1]
newP = 1
else:
newP = 0
if abs(self.__storeR - hpr[2]) > self.__epsilon:
self.__storeR = hpr[2]
newR = 1
else:
newR = 0
# Check for changes:
if not(newX or newY or newZ or newH or newP or newR):
# No change
# Send one and only one "stop" message.
if not self.__storeStop:
self.__storeStop = 1
self.d_setSmStop()
# print 'no change'
elif (newH) and not(newX or newY or newZ or newP or newR):
# Only change in H
self.__storeStop = 0
self.d_setSmH(self.__storeH)
# print ("H change")
elif (newX or newY) and not(newZ or newH or newP or newR):
# Only change in X, Y
self.__storeStop = 0
self.d_setSmXY(self.__storeX, self.__storeY)
# print ("XY change")
elif (newX or newY or newZ) and not(newH or newP or newR):
# Only change in X, Y, Z
self.__storeStop = 0
self.d_setSmPos(self.__storeX, self.__storeY, self.__storeZ)
# print ("XYZ change")
elif (newX or newY or newH) and not(newZ or newP or newR):
# Only change in X, Y, H
self.__storeStop = 0
self.d_setSmXYH(self.__storeX, self.__storeY, self.__storeH)
# print ("XYH change")
elif (newX or newY or newZ or newH) and not(newP or newR):
# Only change in X, Y, Z, H
self.__storeStop = 0
self.d_setSmXYZH(self.__storeX, self.__storeY, self.__storeZ, self.__storeH)
# print ("XYZH change")
else:
# Other changes
self.__storeStop = 0
self.d_setSmPosHpr(self.__storeX, self.__storeY, self.__storeZ,
self.__storeH, self.__storeP, self.__storeR)
# print ("XYZHPR change")
def d_broadcastPosHpr_XYH(self):
# send out the minimal bits to describe our new position
assert not self.isEmpty(), 'DistributedSmoothNode %s has been removed from graph?' % self.doId
xyz = self.getPos()
h = self.getH()
if abs(self.__storeX - xyz[0]) > self.__epsilon:
self.__storeX = xyz[0]
newX = 1
else:
newX = 0
if abs(self.__storeY - xyz[1]) > self.__epsilon:
self.__storeY = xyz[1]
newY = 1
else:
newY = 0
if abs(self.__storeH - h) > self.__epsilon:
self.__storeH = h
newH = 1
else:
newH = 0
# Check for changes:
if not(newX or newY or newH):
# No change
# Send one and only one "stop" message.
if not self.__storeStop:
self.__storeStop = 1
self.d_setSmStop()
# print 'no change'
elif (newH) and not(newX or newY):
# Only change in H
self.__storeStop = 0
self.d_setSmH(self.__storeH)
# print ("H change")
elif (newX or newY) and not(newH):
# Only change in X, Y
self.__storeStop = 0
self.d_setSmXY(self.__storeX, self.__storeY)
# print ("XY change")
else:
# Only change in X, Y, H
self.__storeStop = 0
self.d_setSmXYH(self.__storeX, self.__storeY, self.__storeH)
# print ("XYH change")

View File

@ -18,7 +18,9 @@
#define SOURCES \
config_distributed.cxx config_distributed.h \
cConnectionRepository.cxx cConnectionRepository.I \
cConnectionRepository.h
cConnectionRepository.h \
cDistributedSmoothNodeBase.cxx cDistributedSmoothNodeBase.I \
cDistributedSmoothNodeBase.h
#define IGATESCAN all
#end lib_target

View File

@ -0,0 +1,188 @@
// Filename: cDistributedSmoothNodeBase.I
// Created by: drose (03Sep04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::set_repository
// Access: Published, Static
// Description: Tells the C++ class definition about the AI or Client
// repository, used for sending datagrams.
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
set_repository(CConnectionRepository *repository,
bool is_ai, CHANNEL_TYPE ai_id) {
_repository = repository;
_is_ai = is_ai;
_ai_id = ai_id;
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::set_clock_delta
// Access: Published, Static
// Description: Tells the C++ class definition about the global
// ClockDelta object.
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
set_clock_delta(PyObject *clock_delta) {
_clock_delta = clock_delta;
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::only_changed
// Access: Private, Static
// Description: Returns true if at least some of the bits of compare
// are set in flags, but no bits outside of compare are
// set. That is to say, that the only things that are
// changed are the bits indicated in compare.
////////////////////////////////////////////////////////////////////
INLINE bool CDistributedSmoothNodeBase::
only_changed(int flags, int compare) {
return (flags & compare) != 0 && (flags & ~compare) == 0;
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::d_setSmStop
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
d_setSmStop() {
DCPacker packer;
begin_send_update(packer, "setSmStop");
finish_send_update(packer);
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::d_setSmH
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
d_setSmH(float h) {
DCPacker packer;
begin_send_update(packer, "setSmH");
packer.pack_double(h);
finish_send_update(packer);
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::d_setSmXY
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
d_setSmXY(float x, float y) {
DCPacker packer;
begin_send_update(packer, "setSmXY");
packer.pack_double(x);
packer.pack_double(y);
finish_send_update(packer);
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::d_setSmXZ
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
d_setSmXZ(float x, float z) {
DCPacker packer;
begin_send_update(packer, "setSmXZ");
packer.pack_double(x);
packer.pack_double(z);
finish_send_update(packer);
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::d_setSmPos
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
d_setSmPos(float x, float y, float z) {
DCPacker packer;
begin_send_update(packer, "setSmPos");
packer.pack_double(x);
packer.pack_double(y);
packer.pack_double(z);
finish_send_update(packer);
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::d_setSmHpr
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
d_setSmHpr(float h, float p, float r) {
DCPacker packer;
begin_send_update(packer, "setSmHpr");
packer.pack_double(h);
packer.pack_double(p);
packer.pack_double(r);
finish_send_update(packer);
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::d_setSmXYH
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
d_setSmXYH(float x, float y, float h) {
DCPacker packer;
begin_send_update(packer, "setSmXYH");
packer.pack_double(x);
packer.pack_double(y);
packer.pack_double(h);
finish_send_update(packer);
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::d_setSmXYZH
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
d_setSmXYZH(float x, float y, float z, float h) {
DCPacker packer;
begin_send_update(packer, "setSmXYZH");
packer.pack_double(x);
packer.pack_double(y);
packer.pack_double(z);
packer.pack_double(h);
finish_send_update(packer);
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::d_setSmPosHpr
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE void CDistributedSmoothNodeBase::
d_setSmPosHpr(float x, float y, float z, float h, float p, float r) {
DCPacker packer;
begin_send_update(packer, "setSmPosHpr");
packer.pack_double(x);
packer.pack_double(y);
packer.pack_double(z);
packer.pack_double(h);
packer.pack_double(p);
packer.pack_double(r);
finish_send_update(packer);
}

View File

@ -0,0 +1,284 @@
// Filename: cDistributedSmoothNodeBase.cxx
// Created by: drose (03Sep04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "cDistributedSmoothNodeBase.h"
#include "cConnectionRepository.h"
#include "dcField.h"
#include "dcClass.h"
#include "dcmsgtypes.h"
static const float smooth_node_epsilon = 0.01;
static const double network_time_precision = 100.0; // Matches ClockDelta.py
CConnectionRepository *CDistributedSmoothNodeBase::_repository = NULL;
bool CDistributedSmoothNodeBase::_is_ai;
CHANNEL_TYPE CDistributedSmoothNodeBase::_ai_id;
PyObject *CDistributedSmoothNodeBase::_clock_delta = NULL;
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CDistributedSmoothNodeBase::
CDistributedSmoothNodeBase() {
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CDistributedSmoothNodeBase::
~CDistributedSmoothNodeBase() {
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::initialize
// Access: Published
// Description: Initializes the internal structures from some
// constructs that are normally stored only in Python.
// Also reads the current node's pos & hpr values in
// preparation for transmitting them via one of the
// broadcast_pos_hpr_*() methods.
////////////////////////////////////////////////////////////////////
void CDistributedSmoothNodeBase::
initialize(const NodePath &node_path, DCClass *dclass, CHANNEL_TYPE do_id) {
_node_path = node_path;
_dclass = dclass;
_do_id = do_id;
nassertv(!_node_path.is_empty());
_store_xyz = _node_path.get_pos();
_store_hpr = _node_path.get_hpr();
_store_stop = false;
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::send_everything
// Access: Published
// Description: Broadcasts the current pos/hpr in its complete form.
////////////////////////////////////////////////////////////////////
void CDistributedSmoothNodeBase::
send_everything() {
d_setSmPosHpr(_store_xyz[0], _store_xyz[1], _store_xyz[2],
_store_hpr[0], _store_hpr[1], _store_hpr[2]);
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::broadcast_pos_hpr_full
// Access: Published
// Description: Examines the complete pos/hpr information to see
// which of the six elements have changed, and
// broadcasts the appropriate messages.
////////////////////////////////////////////////////////////////////
void CDistributedSmoothNodeBase::
broadcast_pos_hpr_full() {
LPoint3f xyz = _node_path.get_pos();
LVecBase3f hpr = _node_path.get_hpr();
int flags = 0;
if (!IS_THRESHOLD_EQUAL(_store_xyz[0], xyz[0], smooth_node_epsilon)) {
_store_xyz[0] = xyz[0];
flags |= F_new_x;
}
if (!IS_THRESHOLD_EQUAL(_store_xyz[1], xyz[1], smooth_node_epsilon)) {
_store_xyz[1] = xyz[1];
flags |= F_new_y;
}
if (!IS_THRESHOLD_EQUAL(_store_xyz[2], xyz[2], smooth_node_epsilon)) {
_store_xyz[2] = xyz[2];
flags |= F_new_z;
}
if (!IS_THRESHOLD_EQUAL(_store_hpr[0], hpr[0], smooth_node_epsilon)) {
_store_hpr[0] = hpr[0];
flags |= F_new_h;
}
if (!IS_THRESHOLD_EQUAL(_store_hpr[1], hpr[1], smooth_node_epsilon)) {
_store_hpr[1] = hpr[1];
flags |= F_new_p;
}
if (!IS_THRESHOLD_EQUAL(_store_hpr[2], hpr[2], smooth_node_epsilon)) {
_store_hpr[2] = hpr[2];
flags |= F_new_r;
}
if (flags == 0) {
// No change. Send one and only one "stop" message.
if (!_store_stop) {
_store_stop = true;
d_setSmStop();
}
} else if (only_changed(flags, F_new_h)) {
// Only change in H.
_store_stop = false;
d_setSmH(_store_hpr[0]);
} else if (only_changed(flags, F_new_x | F_new_y)) {
// Only change in X, Y
_store_stop = false;
d_setSmXY(_store_xyz[0], _store_xyz[1]);
} else if (only_changed(flags, F_new_x | F_new_z)) {
// Only change in X, Z
_store_stop = false;
d_setSmXZ(_store_xyz[0], _store_xyz[2]);
} else if (only_changed(flags, F_new_x | F_new_y | F_new_z)) {
// Only change in X, Y, Z
_store_stop = false;
d_setSmPos(_store_xyz[0], _store_xyz[1], _store_xyz[2]);
} else if (only_changed(flags, F_new_h | F_new_p | F_new_r)) {
// Only change in H, P, R
_store_stop = false;
d_setSmHpr(_store_hpr[0], _store_hpr[1], _store_hpr[2]);
} else if (only_changed(flags, F_new_x | F_new_y | F_new_h)) {
// Only change in X, Y, H
_store_stop = false;
d_setSmXYH(_store_xyz[0], _store_xyz[1], _store_hpr[0]);
} else if (only_changed(flags, F_new_x | F_new_y | F_new_z | F_new_h)) {
// Only change in X, Y, Z, H
_store_stop = false;
d_setSmXYZH(_store_xyz[0], _store_xyz[1], _store_xyz[2], _store_hpr[0]);
} else {
// Any other change
_store_stop = false;
d_setSmPosHpr(_store_xyz[0], _store_xyz[1], _store_xyz[2],
_store_hpr[0], _store_hpr[1], _store_hpr[2]);
}
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::broadcast_pos_hpr_xyh
// Access: Published
// Description: Examines only X, Y, and H of the pos/hpr information,
// and broadcasts the appropriate messages.
////////////////////////////////////////////////////////////////////
void CDistributedSmoothNodeBase::
broadcast_pos_hpr_xyh() {
LPoint3f xyz = _node_path.get_pos();
LVecBase3f hpr = _node_path.get_hpr();
int flags = 0;
if (!IS_THRESHOLD_EQUAL(_store_xyz[0], xyz[0], smooth_node_epsilon)) {
_store_xyz[0] = xyz[0];
flags |= F_new_x;
}
if (!IS_THRESHOLD_EQUAL(_store_xyz[1], xyz[1], smooth_node_epsilon)) {
_store_xyz[1] = xyz[1];
flags |= F_new_y;
}
if (!IS_THRESHOLD_EQUAL(_store_hpr[0], hpr[0], smooth_node_epsilon)) {
_store_hpr[0] = hpr[0];
flags |= F_new_h;
}
if (flags == 0) {
// No change. Send one and only one "stop" message.
if (!_store_stop) {
_store_stop = true;
d_setSmStop();
}
} else if (only_changed(flags, F_new_h)) {
// Only change in H.
_store_stop = false;
d_setSmH(_store_hpr[0]);
} else if (only_changed(flags, F_new_x | F_new_y)) {
// Only change in X, Y
_store_stop = false;
d_setSmXY(_store_xyz[0], _store_xyz[1]);
} else {
// Any other change.
_store_stop = false;
d_setSmXYH(_store_xyz[0], _store_xyz[1], _store_hpr[0]);
}
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::begin_send_update
// Access: Private
// Description: Fills up the packer with the data appropriate for
// sending an update on the indicated field name, up
// until the arguments.
////////////////////////////////////////////////////////////////////
void CDistributedSmoothNodeBase::
begin_send_update(DCPacker &packer, const string &field_name) {
DCField *field = _dclass->get_field_by_name(field_name);
nassertv(field != (DCField *)NULL);
if (_is_ai) {
packer.RAW_PACK_CHANNEL(_do_id);
packer.RAW_PACK_CHANNEL(_ai_id);
packer.raw_pack_uint8('A');
packer.raw_pack_uint16(STATESERVER_OBJECT_UPDATE_FIELD);
packer.raw_pack_uint32(_do_id);
packer.raw_pack_uint16(field->get_number());
} else {
packer.raw_pack_uint16(CLIENT_OBJECT_UPDATE_FIELD);
packer.raw_pack_uint32(_do_id);
packer.raw_pack_uint16(field->get_number());
}
packer.begin_pack(field);
packer.push();
}
////////////////////////////////////////////////////////////////////
// Function: CDistributedSmoothNodeBase::finish_send_update
// Access: Private
// Description: Appends the timestamp and sends the update.
////////////////////////////////////////////////////////////////////
void CDistributedSmoothNodeBase::
finish_send_update(DCPacker &packer) {
PyObject *clock_delta = PyObject_GetAttrString(_clock_delta, "delta");
nassertv(clock_delta != NULL);
double delta = PyFloat_AsDouble(clock_delta);
Py_DECREF(clock_delta);
double local_time = ClockObject::get_global_clock()->get_frame_time();
short network_time = (short)(int)cfloor(((local_time - delta) * network_time_precision) + 0.5);
packer.pack_int(network_time);
packer.pop();
bool pack_ok = packer.end_pack();
nassertv(pack_ok);
Datagram dg(packer.get_data(), packer.get_length());
_repository->send_datagram(dg);
}

View File

@ -0,0 +1,98 @@
// Filename: cDistributedSmoothNodeBase.h
// Created by: drose (03Sep04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef CDISTRIBUTEDSMOOTHNODEBASE_H
#define CDISTRIBUTEDSMOOTHNODEBASE_H
#include "directbase.h"
#include "nodePath.h"
#include "dcbase.h"
#include "dcPacker.h"
#include "dcPython.h" // to pick up Python.h
class DCClass;
class CConnectionRepository;
////////////////////////////////////////////////////////////////////
// Class : CDistributedSmoothNodeBase
// Description : This class defines some basic methods of
// DistributedSmoothNodeBase which have been moved into
// C++ as a performance optimization.
////////////////////////////////////////////////////////////////////
class EXPCL_DIRECT CDistributedSmoothNodeBase {
PUBLISHED:
CDistributedSmoothNodeBase();
~CDistributedSmoothNodeBase();
INLINE static void
set_repository(CConnectionRepository *repository,
bool is_ai, CHANNEL_TYPE ai_id);
INLINE static void
set_clock_delta(PyObject *clock_delta);
void initialize(const NodePath &node_path, DCClass *dclass,
CHANNEL_TYPE do_id);
void send_everything();
void broadcast_pos_hpr_full();
void broadcast_pos_hpr_xyh();
private:
INLINE static bool only_changed(int flags, int compare);
INLINE void d_setSmStop();
INLINE void d_setSmH(float h);
INLINE void d_setSmXY(float x, float y);
INLINE void d_setSmXZ(float x, float z);
INLINE void d_setSmPos(float x, float y, float z);
INLINE void d_setSmHpr(float h, float p, float r);
INLINE void d_setSmXYH(float x, float y, float h);
INLINE void d_setSmXYZH(float x, float y, float z, float h);
INLINE void d_setSmPosHpr(float x, float y, float z, float h, float p, float r);
void begin_send_update(DCPacker &packer, const string &field_name);
void finish_send_update(DCPacker &packer);
enum Flags {
F_new_x = 0x01,
F_new_y = 0x02,
F_new_z = 0x04,
F_new_h = 0x08,
F_new_p = 0x10,
F_new_r = 0x20,
};
NodePath _node_path;
DCClass *_dclass;
CHANNEL_TYPE _do_id;
static CConnectionRepository *_repository;
static bool _is_ai;
static CHANNEL_TYPE _ai_id;
static PyObject *_clock_delta;
LPoint3f _store_xyz;
LVecBase3f _store_hpr;
bool _store_stop;
};
#include "cDistributedSmoothNodeBase.I"
#endif // CDISTRIBUTEDSMOOTHNODEBASE_H