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','')