Graphics.UsingTheDougCameraTclCommand - lordmundi/wikidoctest GitHub Wiki
Using the Camera Tcl Commands
« Using the doug callback command | EDGE User’s Guide | Using the doug plugin command »
EDGE provides an extensive tcl scripting ability to DSP.
The doug.camera command can be used to manipulate or query cameras in the scene.
Simple Directions
The doug.camera commands are best explained via examples. The following example commands should illustrate most of the usage:
doug.camera camA limit -tilt -interval -30 30 -enabled 1
doug.camera camA map -tilt tiltvar -pan panvar -fov fovvar
doug.camera camA animate -tilt -units 0.3 -samples 10 -enabled 1
doug.camera camA set -tilt tiltvar -tilt_offset 30.0
doug.camera camA get -tilt_offset
What's really going on
If the above examples are not enough info, or you need more information about a particular option, the source code implementing the doug.camera command is below:
[Show DOUG_CAMERA_cmd source code][4]
int
DOUG_CAMERA_cmd( ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] )
{
#if 0
doug.camera camA limit -tilt -interval -30 30 -enabled 1
doug.camera camA map -tilt tiltvar -pan panvar -fov fovvar
doug.camera camA animate -tilt -units 0.3 -samples 10 -enabled 1
doug.camera camA set -tilt tiltvar -tilt_offset 30.0
doug.camera camA get -tilt_offset
#endif
# define NODE_SET 0x0001
# define NODE_GET 0x0002
# define NODE_TEST 0x0003
# define NODE_ANIMATE 0x0004
# define NODE_LIMIT 0x0005
# define NODE_MAP 0x0007
# define NODE_INTERVAL 0x0100
# define NODE_FLAGS 0x0200
# define NODE_LAYER 0x0300
# define NODE_TREE_FLAGS 0x0400
static int first_pass = 1;
static Tcl_HashTable commands;
static Tcl_HashTable options;
static Tcl_HashTable proc_camparams;
static DSS_NODE node_str;
DOUG_ANIMATE_CMD *panim;
DOUG_LIMIT_PARAM *plim;
int i, id, new_item;
char buff[1000];
char *sep = " \n\t,;";
char *tok_ptr;
char *tok;
DSS_NODE *pn;
Tcl_HashEntry *entry;
double *pdouble;
float *pfloat;
char *tcl_cmdstr;
int *pint;
int fval;
int reltype;
DOUG_NODE_VAR *pnvar;
double min_vfov = 0.1 / 1.3333;
double max_vfov = 130.0 / 1.3333;
double min_hfov = 0.1;
double max_hfov = 130.0;
int tilt_id = -1;
int pan_id = -1;
DSS_CAM_TYPE *ptype = 0;
DSS_CAM_INFO *pinfo = 0;
if( first_pass )
{
Tcl_InitHashTable( &commands, TCL_STRING_KEYS );
Tcl_InitHashTable( &options, TCL_STRING_KEYS );
Tcl_InitHashTable( &proc_camparams, TCL_STRING_KEYS );
Tcl_SetHashValue( Tcl_CreateHashEntry( &commands, "set", &new_item ), NODE_SET );
Tcl_SetHashValue( Tcl_CreateHashEntry( &commands, "map", &new_item ), NODE_MAP );
Tcl_SetHashValue( Tcl_CreateHashEntry( &commands, "get", &new_item ), NODE_GET );
Tcl_SetHashValue( Tcl_CreateHashEntry( &commands, "animate", &new_item ), NODE_ANIMATE );
Tcl_SetHashValue( Tcl_CreateHashEntry( &commands, "limit", &new_item ), NODE_LIMIT );
Tcl_SetHashValue( Tcl_CreateHashEntry( &options, "-interval", &new_item ), NODE_INTERVAL );
Tcl_SetHashValue( Tcl_CreateHashEntry( &proc_camparams, "-tilt", &new_item ), CAM_MODEL_TILT );
Tcl_SetHashValue( Tcl_CreateHashEntry( &proc_camparams, "-tilt_offset", &new_item ), CAM_TILT_OFFSET );
Tcl_SetHashValue( Tcl_CreateHashEntry( &proc_camparams, "-pan", &new_item ), CAM_MODEL_PAN );
Tcl_SetHashValue( Tcl_CreateHashEntry( &proc_camparams, "-pan_offset", &new_item ), CAM_PAN_OFFSET );
Tcl_SetHashValue( Tcl_CreateHashEntry( &proc_camparams, "-zoom", &new_item ), CAM_MODEL_ZOOM );
Tcl_SetHashValue( Tcl_CreateHashEntry( &proc_camparams, "-fov", &new_item ), CAM_MODEL_FOV );
first_pass = 0;
}
i = 1;
if( (id = DSF_GetNodeID( Tcl_GetString( objv[i] ) )) > -1 )
{
pn = DSV_scene->node_list + id;
i++;
tcl_cmdstr = Tcl_GetString( objv[i] );
/* MAKE SURE ITS A CAMERA TYPE NODE (otherwise ignore command) */
if( pn->type & DSD_IS_CAMERA )
{
/* GET ANY CAMERA SPECIFIC INFO */
if( pinfo = pn->data.cam.caminfo )
{
pan_id = pinfo->pan_id;
tilt_id = pinfo->tilt_id;
if( ptype = pinfo->ptype )
{
min_vfov = ptype->min_fov;
max_vfov = ptype->max_fov;
}
}
/* PROCESS CAMERA COMMAND */
if( entry = Tcl_FindHashEntry( &commands, tcl_cmdstr ) )
{
i++;
switch( (int)Tcl_GetHashValue( entry ) )
{
case NODE_SET: /* PARSE SET COMMANDS */
{
DSF_BgnModifyScene( DSV_scene );
while( i < objc )
{
tcl_cmdstr = Tcl_GetString( objv[i] );
if( entry = Tcl_FindHashEntry( &proc_camparams, tcl_cmdstr ) )
{
/* THIS IS THE INDIRECT CAMERA PARAMETERS */
i++;
if( pn->type & DSD_IS_CAMERA )
DOUG_CAM_setval( id, (int)Tcl_GetHashValue( entry ), Tcl_GetString( objv[i] ) );
i++;
}
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, " set (unknown argument \"", tcl_cmdstr, "\")", NULL );
DSF_EndModifyScene( DSV_scene );
return TCL_ERROR;
}
}
DSF_EndModifyScene( DSV_scene );
}
break;
case NODE_GET:
{
tcl_cmdstr = Tcl_GetString( objv[i] );
if( entry = Tcl_FindHashEntry( &proc_camparams, tcl_cmdstr ) )
{
/* THIS IS INDIRECT CAMERA PARAMETERS */
i++;
Tcl_SetResult( interp, DOUG_CAM_getval( id, (int)Tcl_GetHashValue( entry ) ), TCL_VOLATILE );
}
}
break;
case NODE_MAP:
{
/* NOT DONE */
DSF_BgnSceneAccess( DSV_scene, DSD_READ_ACCESS );
while( i < objc )
{
tcl_cmdstr = Tcl_GetString( objv[i] );
/* FIRST SEE IF PARAMETER IS MAPPABLE VIA THE INDIRECT METHOD (since this is done with tk widgets) */
if( entry = Tcl_FindHashEntry( &proc_camparams, tcl_cmdstr ) )
{
i++;
/* THE FOLLOWING IS ONLY FOR CAMERA TYPE */
if( pn->type & DSD_IS_CAMERA )
{
/* GET NODE VARIABLE AND ASSIGN IT TO THE SPECIFIED TCL-VARIABLE */
pnvar = DOUG_GetNodeVar( Tcl_GetString( objv[i] ), INDIRECT_VAR );
i++;
/* UPDATE THE TCL-VARIABLE TO THE CURRENT NODE VALUE */
pnvar->data.ivar.GetVal = DOUG_CAM_getval;
pnvar->data.ivar.SetVal = DOUG_CAM_setval;
pnvar->data.ivar.type = (int)Tcl_GetHashValue( entry );
pnvar->id = pn - DSV_scene->node_list;
Tcl_UnlinkVar( DSV_doug->interp, pnvar->tclvar );
if( !(pnvar->data.ivar.tclval) || (strlen(pnvar->data.ivar.tclval) < strlen(pnvar->data.ivar.GetVal( pnvar->id, pnvar->data.ivar.type )) ) )
{
if( pnvar->data.ivar.tclval )
Tcl_Free( pnvar->data.ivar.tclval );
pnvar->data.ivar.tclval = (char*)Tcl_Alloc(STRING_VAR_SIZE);
}
Tcl_LinkVar( DSV_doug->interp, pnvar->tclvar, (char*)(&(pnvar->data.ivar.tclval)), TCL_LINK_STRING );
strcpy( pnvar->data.ivar.val, pnvar->data.ivar.GetVal( pnvar->id, pnvar->data.ivar.type ) );
strcpy( pnvar->data.ivar.prev_val, pnvar->data.ivar.val );
strcpy( pnvar->data.ivar.tclval, pnvar->data.ivar.val );
strcpy( pnvar->data.ivar.prev_tclval, pnvar->data.ivar.val );
Tcl_UpdateLinkedVar( DSV_doug->interp, pnvar->tclvar );
}
else
i++;
}
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, " map (unknown argument \"", Tcl_GetString( objv[i] ), "\")", NULL );
DSF_EndSceneAccess();
return TCL_ERROR;
}
}
DSF_EndSceneAccess();
}
break;
case NODE_TEST:
/* NOT DONE */
break;
case NODE_ANIMATE:
{
tcl_cmdstr = Tcl_GetString( objv[i] );
if( entry = Tcl_FindHashEntry( &proc_camparams, tcl_cmdstr ) )
{
i++;
reltype = (int)Tcl_GetHashValue( entry );
entry = Tcl_CreateHashEntry( &procanimate_hash, (char*)((id << 10)|reltype), &new_item );
if( new_item )
{
panim = (DOUG_ANIMATE_CMD*)malloc( sizeof(DOUG_ANIMATE_CMD) );
panim->id = id;
panim->type = PROC_PARAM;
panim->vtype = reltype;
panim->enabled = AUTO_UPDATE;
panim->prev_time = cur_time;
panim->scalevar = NULL;
panim->unitsvar = NULL;
panim->scale = 1.0;
panim->units = 1.0;
panim->samples = 2.0;
panim->GetVal = DOUG_CAM_getval_double;
panim->SetVal = DOUG_CAM_setval_double;
Tcl_SetHashValue( entry, (ClientData)panim );
}
else
{
panim = (DOUG_ANIMATE_CMD*)Tcl_GetHashValue( entry );
panim->id = id;
panim->type = PROC_PARAM;
panim->vtype = reltype;
panim->enabled = AUTO_UPDATE;
panim->prev_time = cur_time;
panim->scalevar = NULL;
panim->unitsvar = NULL;
panim->scale = 1.0;
panim->units = 1.0;
panim->samples = 2.0;
panim->GetVal = DOUG_CAM_getval_double;
panim->SetVal = DOUG_CAM_setval_double;
}
}
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, " animate (invalid argument \"", tcl_cmdstr, "\")", NULL );
return TCL_ERROR;
}
while( i < objc )
{
tok = Tcl_GetString( objv[i] );
i++;
if( !strcmp( tok, "-units" ) )
{
panim->type |= (panim->type & ~ANIM_TYPE) | ANIM_UNIT;
Tcl_GetDoubleFromObj( interp, objv[i], &(panim->units) );
i++;
}
else if( !strcmp( tok, "-rate" ) )
{
panim->type |= (panim->type & ~ANIM_TYPE) | ANIM_RATE;
Tcl_GetDoubleFromObj( interp, objv[i], &(panim->units) );
i++;
}
else if( !strcmp( tok, "-ratevar" ) )
{
panim->type |= (panim->type & ~ANIM_TYPE) | ANIM_RATE;
if( entry = Tcl_FindHashEntry( &var_hash, Tcl_GetString(objv[i]) ) )
panim->unitsvar = (DOUG_USER_VARIABLE*)Tcl_GetHashValue( entry );
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, " animate \n"
"-ratevar (undefined variable \"", Tcl_GetString(objv[i]), "\")", NULL );
return TCL_ERROR;
}
i++;
}
else if( !strcmp( tok, "-unitsvar" ) )
{
panim->type |= (panim->type & ~ANIM_TYPE) | ANIM_UNIT;
if( entry = Tcl_FindHashEntry( &var_hash, Tcl_GetString(objv[i]) ) )
panim->unitsvar = (DOUG_USER_VARIABLE*)Tcl_GetHashValue( entry );
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, " animate \n"
"-unitsvar (undefined variable \"", Tcl_GetString(objv[i]), "\")", NULL );
return TCL_ERROR;
}
i++;
}
else if( !strcmp( tok, "-scalevar" ) )
{
if( entry = Tcl_FindHashEntry( &var_hash, Tcl_GetString( objv[i] ) ) )
panim->scalevar = (DOUG_USER_VARIABLE*)Tcl_GetHashValue( entry );
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, " animate \n"
"-scalevar (undefined variable \"", Tcl_GetString( objv[i] ), "\")", NULL );
return TCL_ERROR;
}
i++;
}
else if( !strcmp( tok, "-samples" ) )
{
Tcl_GetDoubleFromObj( interp, objv[i], &(panim->samples) );
i++;
}
else if( !strcmp( tok, "-reverse" ) )
{
int ival;
Tcl_GetIntFromObj( interp, objv[i], &ival );
if( ival )
panim->enabled |= AUTO_REVERSE;
else
panim->enabled &= ~AUTO_REVERSE;
i++;
}
else if( !strcmp( tok, "-enabled" ) )
{
int ival;
Tcl_GetIntFromObj( interp, objv[i], &ival );
if( ival && !(panim->enabled & AUTO_UPDATE) )
{
panim->prev_time = cur_time;
panim->enabled |= AUTO_UPDATE;
}
else if( !ival )
panim->enabled &= ~AUTO_UPDATE;
i++;
}
else
{
tcl_cmdstr = tok;
/* OHTERWISE SEE IF WE ARE ANIMATING A RELATIVE-PARAMETER */
if( entry = Tcl_FindHashEntry( &proc_camparams, tcl_cmdstr ) )
{
reltype = (int)Tcl_GetHashValue( entry );
entry = Tcl_CreateHashEntry( &procanimate_hash, (char*)((id << 10)|reltype), &new_item );
if( new_item )
{
panim = (DOUG_ANIMATE_CMD*)malloc( sizeof(DOUG_ANIMATE_CMD) );
panim->id = id;
panim->type = PROC_PARAM;
panim->vtype = reltype;
panim->enabled = AUTO_UPDATE;
panim->prev_time = cur_time;
panim->scalevar = NULL;
panim->unitsvar = NULL;
panim->scale = 1.0;
panim->units = 1.0;
panim->samples = 2.0;
panim->GetVal = DOUG_CAM_getval_double;
panim->SetVal = DOUG_CAM_setval_double;
Tcl_SetHashValue( entry, (ClientData)panim );
}
else
{
panim = (DOUG_ANIMATE_CMD*)Tcl_GetHashValue( entry );
panim->id = id;
panim->type = PROC_PARAM;
panim->vtype = reltype;
panim->enabled = AUTO_UPDATE;
panim->prev_time = cur_time;
panim->scalevar = NULL;
panim->unitsvar = NULL;
panim->scale = 1.0;
panim->units = 1.0;
panim->samples = 2.0;
panim->GetVal = DOUG_CAM_getval_double;
panim->SetVal = DOUG_CAM_setval_double;
}
}
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, " animate (invalid argument \"", tcl_cmdstr, "\")", NULL );
return TCL_ERROR;
}
}
}
}
break;
case NODE_LIMIT:
{
tcl_cmdstr = Tcl_GetString( objv[i] );
if( entry = Tcl_FindHashEntry( &proc_camparams, tcl_cmdstr ) )
{
i++;
reltype = (int)Tcl_GetHashValue( entry );
entry = Tcl_CreateHashEntry( &proclimit_hash, (char*)((id << 8)|reltype), &new_item );
if( new_item )
{
plim = (DOUG_LIMIT_PARAM*)malloc( sizeof(DOUG_LIMIT_PARAM) );
Tcl_SetHashValue( entry, (ClientData)plim );
plim->id = id;
plim->indirect = 1;
plim->vtype = reltype;
plim->enabled = 1;
plim->GetVal = DOUG_CAM_getval_double;
plim->SetVal = DOUG_CAM_setval_double;
plim->min = DOUG_CAM_getval_double( id, reltype ) - 0.001;
plim->max = plim->min + 0.002;
}
else
{
plim->id = id;
plim->indirect = 1;
plim->vtype = reltype;
plim->enabled = 1;
}
}
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, " animate (invalid argument \"", tcl_cmdstr, "\")", NULL );
return TCL_ERROR;
}
while( i < objc )
{
tok = Tcl_GetString( objv[i] );
i++;
if( !strcmp( tok, "-interval" ) || !strcmp( tok, "-range" ) )
{
Tcl_GetDoubleFromObj( interp, objv[i], &(plim->min) );
i++;
Tcl_GetDoubleFromObj( interp, objv[i], &(plim->max) );
i++;
if( (plim->max-plim->min) < 0.0001 )
{
plim->min = plim->min - 0.00006;
plim->max = plim->max + 0.00006;
}
}
else if( !strcmp( tok, "-enabled" ) )
{
Tcl_GetIntFromObj( interp, objv[i], &(plim->enabled) );
i++;
}
else
{
tcl_cmdstr = tok;
if( entry = Tcl_FindHashEntry( &proc_camparams, tcl_cmdstr ) )
{
reltype = (int)Tcl_GetHashValue( entry );
entry = Tcl_CreateHashEntry( &proclimit_hash, (char*)((id << 8)|reltype), &new_item );
if( new_item )
{
plim = (DOUG_LIMIT_PARAM*)malloc( sizeof(DOUG_LIMIT_PARAM) );
Tcl_SetHashValue( entry, (ClientData)plim );
plim->id = id;
plim->indirect = 1;
plim->vtype = reltype;
plim->enabled = 1;
plim->GetVal = DOUG_CAM_getval_double;
plim->SetVal = DOUG_CAM_setval_double;
plim->min = DOUG_CAM_getval_double( id, reltype ) - 0.001;
plim->max = plim->min + 0.002;
}
else
{
plim->id = id;
plim->indirect = 1;
plim->vtype = reltype;
plim->enabled = 1;
}
}
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, " animate (invalid argument \"", tcl_cmdstr, "\")", NULL );
return TCL_ERROR;
}
}
}
}
break;
}
}
else
{
Tcl_AppendResult( interp, "doug.camera ", pn->name, "(unknown command \"", Tcl_GetString( objv[i] ), "\")", NULL );
return TCL_ERROR;
}
}
}
return TCL_OK;
}
« Using the doug callback command | EDGE User’s Guide | Using the doug plugin command »
[4]: javascript:toggleObj('togglecode_id0','hide','Show DOUG_CAMERA_cmd source code','Show DOUG_CAMERA_cmd source code','')