Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
fpt.x[0],fpt.x[1],fpt.x[2], minlen);
} else if(!strncmp( argv[0], "jump", 4 )) {
Point xyz;
float aer[3];
static int stupid[3] = {1,0,2}; /* aer -> rx ry rz */
Matrix c2w;
parti_getc2w( &c2w );
tfm2xyzaer( &xyz, aer, &c2w );
if(argc>1) {
for(i=1; i<argc && i<4+3; i++) {
if(i-1<3) xyz.x[i-1] = getfloat(argv[i], xyz.x[i-1]);
else aer[stupid[i-4]] = getfloat(argv[i], aer[stupid[i-4]]);
}
xyzaer2tfm( &c2w, &xyz, aer );
parti_setc2w( &c2w );
}
msg("jump %g %g %g %g %g %g (XYZ RxRyRz)",
xyz.x[0],xyz.x[1],xyz.x[2],
aer[1],aer[0],aer[2]);
} else if(!strncmp( argv[0], "home", 4 )) {//marx version 0.7.03
Point xyz;
float aer[3];
static int stupid[3] = {1,0,2}; /* aer -> rx ry rz */
Matrix c2w;
parti_getc2w( &c2w );
tfm2xyzaer( &xyz, aer, &c2w );
if(argc>1) {
for(i=1; i<argc && i<4+3; i++) {
if(i-1<3) xyz.x[i-1] = getfloat(argv[i], xyz.x[i-1]);
else aer[stupid[i-4]] = getfloat(argv[i], aer[stupid[i-4]]);
}
xyzaer2tfm( &c2w, &xyz, aer );
parti_setc2w( &c2w );
ppszg.home[0] = xyz.x[0]; ppszg.home[1] = xyz.x[1]; ppszg.home[2] = xyz.x[2];
//ppszg.home[3] = aer[0]; ppszg.home[4] = aer[1]; ppszg.home[5] = aer[2]; bug in releases >= 0.7.03
ppszg.home[3] = aer[1]; ppszg.home[4] = aer[0]; ppszg.home[5] = aer[2]; //version 0.7.05 fix for the line above
}
msg("home %g %g %g %g %g %g (XYZ RxRyRz)", ppszg.home[0], ppszg.home[1], ppszg.home[2], ppszg.home[3], ppszg.home[4], ppszg.home[5]);
} else if((!strcmp( argv[0], "rdata" ) || !strcmp(argv[0], "readpath"))
&& argc>1) {
bool freet = false;
char *tfname = argv[1];
char *realfile = findfile( fromfname, tfname );
if(realfile == NULL) {
tfname = (char *)malloc(strlen(argv[1]) + 32);
freet = true;
sprintf(tfname, "data/record/%s%s", argv[1],
strstr(argv[1], ".wf") ? "" : ".wf");
realfile = findfile( NULL, tfname+12 );
}
if(realfile == NULL)
realfile = findfile( fromfname, tfname );
if(realfile)
parti_readpath( realfile );
else
msg("%s: can't find \"%s\" nor data/record/... nor ...wf",
argv[0],argv[1]);
if(freet)
free(tfname);
} else if(!strcmp( argv[0], "play" )) {
parti_play( argc>1 ? rejoinargs(1, argc, argv) : NULL );
} else if(!strcmp( argv[0], "frame" )) {
CONST struct wfpath *pp;
i = parti_frame( argv[1], &pp );
msg("frame %d (of %d..%d)", pp->curframe,
pp->frame0, pp->nframes + pp->frame0 - 1);
} else if(!strcmp( argv[0], "interest") || !strcmp( argv[0], "int" ) ||
!strcmp( argv[0], "center" ) ||
!strcmp( argv[0], "cen" )) {
Point cen;
float censize = parti_getcensize();
parti_getcenter( &cen );
if(argc > 1) {
sscanf(argv[1], "%f%*c%f%*c%f%*c%f",
&cen.x[0],&cen.x[1],&cen.x[2], &censize);
if(argc > 3)
for(i=0;i<3;i++)
cen.x[i] = getfloat(argv[i+1], cen.x[i]);
if(argc == 3 || argc == 5)
sscanf(argv[argc-1], "%f", &censize);
parti_center( &cen );
if(censize != parti_getcensize())
parti_censize( censize );
}
msg("center %g %g %g %g(radius)", cen.x[0],cen.x[1],cen.x[2], censize);
} else if(!strcmp( argv[0], "censize" )) {
if(argc>1)
parti_censize( getfloat(argv[1], parti_getcensize()));
msg("censize %g (interest-marker size)", parti_getcensize());
} else {
return 0;
}
return 1;
}
void pp_ui_postinit() {
parti_set_timebase( ppszg.st, 0.0 );
parti_set_timestep( ppszg.st, 0.0 );
parti_set_running( ppszg.st, 0 );
parti_set_fwd( ppszg.st, 1 );
}
void clearBuffer(char* buf, int bufsize)
{
for(int i=0; i < bufsize; i++)
{
buf[i] = '\0';
}
}
PpCmd::PpCmd( CmdType type, int argc, char **argv )
{
this->type = type;
this->argc = argc;
this->argv = argv;
}
PpCmd::~PpCmd() {
}
int PpCmd::frozenLen() const {
int len = 2*argc+2;
for(int i = 0; i < argc; i++)
len += strlen(argv[i]);
return len;
}
/* Serialize the command, and append result to 'buf' */
int PpCmd::freezeInto( string &buf ) const {
int ineed = buf.size() + frozenLen() + 1;
if(buf.capacity() < ineed)
buf.reserve( 2*ineed+1 );
for(int i = 0; i < argc; i++) {
buf.append( argv[i], strlen(argv[i]) );
buf.append( 1, '\000' );
buf.append( 1, '\000' ); // mark end of last arg
return buf.size();
int PpCmd::thawFrom( char *buf, int &offset, bool copystrings ) {
if(buf == 0)
return 0;
int p = offset;
argc = 0;
argv = 0;
type = (CmdType) buf[p];
switch(type) {
case CMD_DATA:
case CMD_CONTROL:
break; // OK.
default:
msg("PpCmd::thawFrom(): Trouble decoding %p at offset %d (got 0x%x not 0/1/2)", buf, p, buf[p]);
type = CMD_NONE;
return -1;
}
// count args
do {
p++;
p += strlen( &buf[p] ) + 1;
argc++;
} while(buf[p] != 0);
argv = new char *[argc+1];
// msg("Found %d args in thawing %d bytes from offset %d", argc, p-offset, offset);
// copy args
p = offset;
for(int a = 0; a < argc; a++) {
p++;
argv[a] = copystrings ? strdup(&buf[p]) : &buf[p];
p += strlen(&buf[p]) + 1;
}
argv[argc] = 0;
offset = p+1;
return argc;
}
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
Ppszg::~Ppszg() {
delete scene;
// delete clk; Don't delete the clock -- might be shared with other objects
}
Ppszg::Ppszg() {
scene = new PvScene();
st = NULL;
clipnear_ = 0.1;
clipfar_ = 2500;
focallen_ = 3;
snapfmt = NULL;
snapfno = 0;
pickrange = 3.5;
memset(home, 0, sizeof(home));
clk = new SClock();
clock_init( clk );
clock_set_speed( clk, 1.0 );
clk->continuous = 1;
clk->walltimed = 1;
memset( &path, 0, sizeof(path) );
playing = 0;
playevery = 0;
playidling = 0;
playspeed = 20;
framebase = 1;
playtimebase = 0;
playloop = 0;
timebasetime = 0;
subcam = 0;
/* List of connected arSockets */
socketList = NULL;
bool Ppszg::onStart( arSZGClient& SZGClient ) {
/*
* Add Transfer Fields to Framework so data is
* accessible and syncronized to all clients
* Added July 23, 2008 William Davis
*/
processid = SZGClient.getProcessID(); // for msg() log files
addTransferField("curtime", &(ppszg.clk->curtime), AR_DOUBLE, 1);
addTransferField("running", &(ppszg.clk->running), AR_INT, 1);
addTransferField("continuous", &(ppszg.clk->continuous), AR_INT, 1);
addTransferField("center_", &(ppszg.scene->center_), AR_FLOAT, 3);
addTransferField("censize_", &(ppszg.scene->censize_), AR_FLOAT, 1);
addTransferField("quitnow", &(ppszg.quitnow_), AR_INT, 1);
addInternalTransferField( "commands", AR_CHAR, 1 );
parti_bgcolor( "0 0 0" );
parti_add_commands( pp_parse_args, "partiview", NULL );
parti_add_reader( pp_read, "partiview", NULL );
plugin_init();
// pp_ui_init();
// ppui.view->pickbuffer( COUNT(pickbuffer), pickbuffer );
parti_clip( "0.1", "2500" );
parti_censize( 1.0 );
// parti_pickrange( 3.5 );
parti_object( "g1", NULL, 1 );
readrc( &ppszg.st );
for(int i = 1; i < globalArgc; i++) {
slevy
committed
if(0==strcmp(globalArgv[i], "-c") && i+1 < globalArgc) {
i++;
int len = strlen(globalArgv[i]);
int maxargs = len/2 + 2; // max possible number of args
char **av = new char *[maxargs];
char tbuf[ 2*len + 1024 ];
int ac = tokenize( globalArgv[i], tbuf, maxargs, av, NULL );
if(! specks_parse_args( &ppszg.st, ac, av )) {
msg("-c: Unrecognized control command: %s", globalArgv[i]);
}
delete av;
} else if(0 == strcmp(globalArgv[i], "-fly")) {
flyer.config( globalArgv[++i] );
slevy
committed
} else if(0 == strcmp(globalArgv[i], "-plog")) {
partiLog++;
} else {
specks_read( &ppszg.st, globalArgv[i] );
}
// pp_ui_postinit();
return true;
#if 0
bool arMasterSlaveFramework::addInternalTransferField( std::string fieldName,
arDataType dataType,
int numElements );
The pointer argument is omitted, and the numElements argument now denotes the initial size. The size can be changed by calling:
bool arMasterSlaveFramework::setInternalTransferFieldSize( std::string fieldName,
arDataType dataType,
int newSize );
#endif
void Ppszg::onWindowStartGL( arGUIWindowInfo * ) {
set_dsp_context( 0 ); /* assign a display context, so texture code can track window changes */
}
void Ppszg::onPreExchange( void ) { // called on master only
// do navigation...
// process commands read from network...
// and package any with
/* Here we want to do the listening on the sockets to interpret
* any commands we might receive over them
*/
static int socketid = 0;
if(ppszg.listenSocket == 0) {
// Create listener socket. Do this only in a *live* master
/* arSockets - originally from salimiman by Jim Crowell */
msg("master on pid %d listening on port 8675", processid);
listenSocket = new arSocket(AR_LISTENING_SOCKET);
listenSocket->ar_create();
listenSocket->setSendBufferSize(2048);
listenSocket->setReceiveBufferSize(2048);
listenSocket->reuseAddress(true);
list<string> acceptMask;
listenSocket->setAcceptMask(acceptMask);
/* Bind to port 8675 */
listenSocket->ar_bind(NULL, 8675);
listenSocket->ar_listen(256);
}
if(ppszg.listenSocket->readable())
{
bufferedSocket* sockp = new bufferedSocket();
arSocketAddress addr;
ppszg.listenSocket->ar_accept(sockp, &addr);
msg("process %d accepted connection", processid);
sockp->setID(socketid++);
sockp->next = ppszg.socketList;
ppszg.socketList = sockp;
/* "fly" navigation if selected */
flyer.navUpdate();
cmdbuf_.clear(); // wipe master->slaves buffer for this cycle
/* Now read data into the buffer */
bufferedSocket* sock = ppszg.socketList;
bufferedSocket** previousSocketp = &ppszg.socketList;
int len = sock->poll();
while(len >= 0) { // repeat for all the lines in buffer
int maxargs = len/2 + 2; // max possible number of args
char **av = new char *[maxargs];
char tbuf[ 2*len + 1024 ];
// temp buffer. Extra room allows for $expansion etc.
// XXX should pass this length to tokenize!
int ac = tokenize( sock->str(), tbuf, maxargs, av, NULL );
if(ac > 0) {
// Not a comment nor a blank line. Try to parse it locally.
if( ! specks_parse_args( &ppszg.st, ac, av ) ) {
msg("Unrecognized control command: %s", sock->str());
}
// In any case, pass it on to slaves
PpCmd cmd( CMD_CONTROL, ac, av );
cmd.freezeInto( cmdbuf_ );
}
delete av;
len = sock->consume(); // Done processing that line. Got another on hand?
}
if(sock->expired()) {
*previousSocketp = sock->next;
delete sock;
} else {
previousSocketp = &sock->next;
}
sock = *previousSocketp;
}
// Now ship bundled commands to slaves
if(cmdbuf_.size() == 0)
cmdbuf_.append( 1, '\000' ); // ensure nonzero size
setInternalTransferFieldSize( "commands", AR_CHAR, cmdbuf_.size() );
if(cmdbuf_.size() > 1 && getenv("CMDTEST")) {
PpCmd tcmd;
int offset = 0;
int room = cmdbuf_.size();
msg("Got %d-bytes of command packet", room-1); // XXX DEBUG
while(offset+1 < room) {
int oof = offset;
if( tcmd.thawFrom( &cmdbuf_[0], offset, false ) < 0)
break;
// false -> build argc/argv which point into cmdp string directly
msg("Offset %d..%d: command [%d] %s", oof,offset, tcmd.argc, rejoinargs( 0, tcmd.argc, tcmd.argv ));
if(tcmd.argc <= 0 || oof == offset) {
msg("Had enough: tcmd.argc=%d, offset %d, room %d", tcmd.argc, offset, room);
break;
}
}
}
int room = 0;
char *cmdp = (char *)getTransferField( "commands", AR_CHAR, room );
if(cmdp == 0 || room != cmdbuf_.size()) {
msg("panic: transfer field size %d != the size %d we told it to be!\n",
room, cmdbuf_.size());
} else {
memcpy( cmdp, &cmdbuf_[0], room );
}
/*
* Added July 23, 2008 William Davis
* Forces the framework to listen to updates to navigation matrix
* changed from a "jump" command
*/
navUpdate();
clock_tick( ppszg.clk ); // let time advance
}
void Ppszg::onPostExchange( void ) // called on master + slaves
{
if(! this->getMaster() ) {
// We're a slave. Decode any commands passed by master this cycle.
int room = 0;
char *cmdp = (char *)getTransferField( "commands", AR_CHAR, room );
if(cmdp == 0) {
static int once = 1;
if(once) msg("Ppszg::onPostExchange: can't get transfer field \"commands\"");
once = 0;
return;
}
#if 0
if(room > 1) {
msg("postExchange: GOT %d-bytes of cmd pkt", room-1);
char unk[512];
int u,uu;
for(u=uu=0; u<room; u++)
uu += sprintf(&unk[uu], cmdp[u]<' ' ? "\\x%02x" : "%c", cmdp[u]);
unk[uu] = '\0';
msg("Received: \"%s\"", unk); // XXX debug
}
#endif
int oof = offset;
bool done;
done = (pp.thawFrom( cmdp, offset, false ) < 0);
// false -> build argc/argv which point into cmdp string directly
if(done || oof >= offset || pp.argc <= 0) {
msg("Had enough of cmd pkt: done %d offset %d was %d, room %d, argc %d, type 0x%x", done, offset, oof, room, pp.argc, pp.type);
break;
}
msg("postExchange: processing '%s'", rejoinargs(0,pp.argc,pp.argv));
if(pp.type == CMD_CONTROL) {
if(! specks_parse_args( &ppszg.st, pp.argc, pp.argv ) ) {
warn("Unrecognized control command on slave: %s",
rejoinargs( 0, pp.argc, pp.argv ));
}
} else {
warn("can only handle control cmds, not: %s",
rejoinargs(0, pp.argc, pp.argv));
}
}
}
/* terminate if we're asked to... */
/* is this the right way to do this? */
if(ppszg.quitnow_)
exit(0);
}
void Ppszg::onWindowInit( void ) { // clear to background...
glClearColor( bgcolor.x[0], bgcolor.x[1], bgcolor.x[2], 1 );
ar_defaultWindowInitCallback();
}
void Ppszg::onDraw( arGraphicsWindow& win, arViewport& vp ) {
* Added July 23, 2008 William Davis
* Loads the navigation matrix into the framework, making
* sure we listen to the changes enacted by the "jump" command
* in parti_setc2w()
*/
loadNavMatrix();
scene->draw();
}
void Ppszg::onDisconnectDraw( void ) {
glClearColor( 1, .1, .1, 1 );
glClear( GL_COLOR_BUFFER_BIT );
}
void Ppszg::onCleanup( void ) {
}
void Ppszg::onUserMessage( const string& messageBody ) {
// called in master on "dex <N> user <some message for this program>"
// parse messageBody, add to command queue for next preExchange time
}
#ifdef __linux__
#include <GL/glut.h> // hack: Syzygy uses glutWireSphere() in simulator mode, but freeglut insists on glutInit() first
#endif
int main(int argc, char *argv[])
{
#ifdef __linux__
int targc = 1; // rest of hack.
glutInit( &targc, argv );
#endif
globalArgc = argc; //Make these two variables accessible to the
globalArgv = argv; // onStart callback
if( ! ppszg.init( argc, argv ) ) {
fprintf(stderr, "arMasterSlaveFramework::init() failed, giving up...\n");
exit(1);
}
if( ! ppszg.start() ) {
fprintf(stderr, "arMasterSlaveFramework::start() failed, giving up...\n");
exit(1);
}
// Shouldn't reach here.
fprintf(stderr, "Shouldn't reach here.\n");
exit(2);
}