szgPartiview.h 7.57 KiB
#ifndef _SZGPARTIVIEW_H
#define _SZGPARTIVIEW_H
/*
* Main scene data for szgPartiview.
*/
#include "arPrecompiled.h"
#include "arMasterSlaveFramework.h"
#include "arSocket.h"
#ifdef WIN32
# include "winjunk.h"
#endif
#include "specks.h"
#include "partiviewc.h"
#include <vector>
typedef struct subcam {
char name[8];
float azim, elev, roll;
float nleft, right, ndown, up;
} Subcam;
struct PvObject {
struct stuff *st_;
Matrix To2w_;
char *name_;
int id_; // id in parent's list of objects
int parent_; /* 0=world, GV_ID_CAMERA=attach-to-camera */
PvObject();
PvObject( const char *name, int id );
void init( const char *name, int id );
Matrix *To2w() { return &To2w_; }
void To2w( const Matrix *T ) { To2w_ = *T; }
int parent() const { return parent_; } // 0 if ordinary, -1 if parent is camera
void parent(int p) { parent_ = p; }
int id() const { return id_; }
void draw( bool inpick = false );
struct stuff *objstuff() { return st_; }
};
struct PvScene {
Point center_;
float censize_;
std::vector <class PvObject> objs_;
PvScene() {
center_.x[0] = center_.x[1] = center_.x[2] = 0;
censize_ = 1.0;
}
const Point *center() const { return ¢er_; }
void center( const Point *p ) { center_ = *p; }
float censize() const { return censize_; }
void censize( float s ) { censize_ = s; }
PvObject *obj( int id ) { return ((unsigned int)id < objs_.size()) ? &objs_[id] : 0; }
struct stuff *objstuff( int id ) {
PvObject *ob = obj(id);
return ob ? ob->objstuff() : 0;
}
int nobjs() const { return objs_.size(); }
PvObject *addobj( const char *name, int id = -1 );
void draw( bool inpick = false );
};
// For queueing commands for network transmission
typedef enum { CMD_NONE=0, CMD_DATA=1, CMD_CONTROL=2 } CmdType;
class bufferedSocket : public arSocket {
public:
string buf;
bool seeneof;
int linelen;
bufferedSocket *next;
bufferedSocket() : arSocket(AR_STANDARD_SOCKET), buf(), seeneof(false), linelen(-1), next(NULL)
{
buf.reserve(100);
}
// Time to give up and close this socket?
// Yes if seeneof *and* there's no data in the buffer.
bool expired() const {
return seeneof && linelen < 0;
}
// Check for data and append to string.
// Returns length of available data, or -1 if none ready yet.
// If we return -1 AND seeneof is true, it's time to toss this socket.
//
// If poll() return >= 0, you should use str() as a returned string,
// and then call consume() to say you've finished using the data.
int poll() {
char tbuf[512];
while(!seeneof && readable()) {
int got = ar_read(tbuf, sizeof(tbuf));
if(got < 0) {
seeneof = true;
if(!buf.empty()) {
linelen = buf.size(); // yes EOF, but we have data to hand off first.
buf.append( 1, '\0' ); // add terminating NUL
}
break;
}
buf.append( tbuf, got ); // append it to previous data
if(linelen < 0) {
char *newline = (char *)memchr(tbuf, '\n', got);
if(newline != 0) { // Yep.
linelen = buf.size() - got + (newline - tbuf);
buf[linelen] = '\0'; // Replace final \n or \r\n with \0 or \0\0
if(linelen > 0 && buf[linelen] == '\r')
buf[linelen - 1] = '\0';
}
}
if(got < sizeof(tbuf))
break;
}
return linelen;
}
char *str() {
return &buf[0]; // Return pointer to line, which should be a \000-terminated string.
// Only valid if linelen >= 0.
}
// Consume current line -- indicate that we no longer need the data returned by str().
// Return value is just like poll():
// If there's (another) line in the buffer (after the consumed one),
// then return its length, else -1.
int consume() {
if(linelen >= 0) {
// have any data following the \n?
if(buf.size() > linelen+1) {
int newsize = buf.size() - (linelen+1);
memmove(&buf[0], &buf[linelen+1], newsize);
buf.resize( newsize );
char *newline = (char *)memchr(&buf[0], '\n', newsize);
if(newline) {
linelen = newline - &buf[0];
buf[linelen] = '\0';
if(linelen > 0 && buf[linelen-1] == '\r')
buf[linelen-1] = '\0';
} else {
linelen = -1;
}
} else {
buf.resize(0);
linelen = -1;
}
}
return linelen;
}
};
class PpCmd {
public:
CmdType type;
int argc;
char **argv;
PpCmd() { type = CMD_DATA; argc = -1; argv = 0; }
PpCmd( CmdType, int argc, char **argv );
~PpCmd();
int frozenLen() const; // length of serialized data including terminating 000
int freezeInto( string &str ) const;
int thawFrom( char *buf, int &offset, bool copystrings = true );
};
struct Ppszg : public arMasterSlaveFramework {
PvScene *scene;
// XXX Could have a draw callback kinda like
// XXX void draw() {
// glClearColor( bgcolor.x[0],bgcolor.x[1],bgcolor.x[2], 1 );
// glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); // or however you do background color in szg
// scene->draw();
// }
struct stuff *st; // ref for currently selected Object
Point bgcolor;
float clipnear_, clipfar_;
float focallen_;
string cmdbuf_; // master->slave command transfer buf
Ppszg();
~Ppszg();
void nearclip( float s ) { clipnear_ = s; }
void farclip( float s ) { clipfar_ = s; }
float nearclip() const { return clipnear_; }
float farclip() const { return clipfar_; }
void focallen(float dist) { focallen_ = dist; }
float focallen() const { return focallen_; }
char *snapfmt;
int snapfno;
float pickrange;
float home[6]; //marx marx version 0.7.03 home is equivalent to a jump to a named point of view
SClock *clk; // master data clock
vector <PpCmd> cmdqueue;
/* camera animation stuff */
struct wfpath path;
int playing;
int playevery;
int playidling;
float playspeed;
int framebase;
float playtimebase;
int playloop;
double timebasetime;
std::vector <Subcam> sc;
int subcam;
void queueCmd( bool datacommand, int argc, char *argv[] );
// implementing arMasterSlaveFramework methods:
virtual bool onStart( arSZGClient& SZGClient );
virtual void onWindowStartGL( arGUIWindowInfo * );
virtual void onPreExchange( void ); // called on master only
virtual void onPostExchange( void ); // called on master + slaves
virtual void onWindowInit( void ); // clear to background... ar_defaultWindowInitCallback()
virtual void onDraw( arGraphicsWindow& win, arViewport& vp );
virtual void onDisconnectDraw( void );
virtual void onCleanup( void );
virtual void onUserMessage( const string& messageBody );
// arSocket stuff
arSocket* listenSocket;
bufferedSocket* socketList;
};
extern struct Ppszg ppszg;
extern void ppszg_refresh( struct stuff * );
extern int specks_commandfmt( struct stuff **, const char *fmt, ... );
#endif /*_SZGPARTIVIEW_H*/