Пример #1
0
// do the edges of polya and polyb collide? (Does NOT test for containment).
int g2d_polygon_intersects_polygon(const zarray_t *polya, const zarray_t *polyb)
{
    // do any of the line segments collide? If so, the answer is no.

    // dumb N^2 method.
    for (int ia = 0; ia < zarray_size(polya); ia++) {
        double pa0[2], pa1[2];
        zarray_get(polya, ia, pa0);
        zarray_get(polya, (ia+1)%zarray_size(polya), pa1);

        g2d_line_segment_t sega;
        g2d_line_segment_init_from_points(&sega, pa0, pa1);

        for (int ib = 0; ib < zarray_size(polyb); ib++) {
            double pb0[2], pb1[2];
            zarray_get(polyb, ib, pb0);
            zarray_get(polyb, (ib+1)%zarray_size(polyb), pb1);

            g2d_line_segment_t segb;
            g2d_line_segment_init_from_points(&segb, pb0, pb1);

            if (g2d_line_segment_intersect_segment(&sega, &segb, NULL))
                return 1;
        }
    }

    return 0;
}
Пример #2
0
// compute a point that is inside the polygon. (It may not be *far* inside though)
void g2d_polygon_get_interior_point(const zarray_t *poly, double *p)
{
    // take the first three points, which form a triangle. Find the middle point
    double a[2], b[2], c[2];

    zarray_get(poly, 0, a);
    zarray_get(poly, 1, b);
    zarray_get(poly, 2, c);

    p[0] = (a[0]+b[0]+c[0])/3;
    p[1] = (a[1]+b[1]+c[1])/3;
}
Пример #3
0
void
getopt_do_usage (getopt_t *gopt)
{
    int leftmargin=2;
    int longwidth=12;
    int valuewidth=10;

    for (unsigned int i = 0; i < zarray_size (gopt->options); i++) {
        getopt_option_t *goo = NULL;
        zarray_get (gopt->options, i, &goo);

        if (goo->spacer)
            continue;

        longwidth = max (longwidth, strlen(goo->lname));

        if (goo->type == GOO_STRING_TYPE)
            valuewidth = max (valuewidth, strlen(goo->svalue));
    }

    for (unsigned int i = 0; i < zarray_size (gopt->options); i++) {
        getopt_option_t *goo = NULL;
        zarray_get (gopt->options, i, &goo);

        if (goo->spacer) {
            if (goo->help==NULL || 0==strlen (goo->help))
                printf ("\n");
            else
                printf ("\n%*s%s\n\n", leftmargin, "", goo->help);
            continue;
        }

        printf ("%*s", leftmargin, "");

        if (goo->sname[0]==0)
            printf ("     ");
        else
            printf ("-%c | ", goo->sname[0]);

        printf ("--%*s ", -longwidth, goo->lname);

        printf (" [ %s ]", goo->svalue); // XXX: displays current value rather than default value

        printf ("%*s", (int) (valuewidth-strlen (goo->svalue)), "");

        printf (" %s   ", goo->help);
        printf ("\n");
    }
}
Пример #4
0
// returns null def if no parameter specified.
const char *
url_parser_get_parameter (url_parser_t *urlp, const char *key, const char *def)
{
    for (int i = 0; i < zarray_size(urlp->keys); i++) {
        char *thiskey;
        zarray_get(urlp->keys, i, &thiskey);
        if (!strcmp(thiskey, key)) {
            char *val;
            zarray_get(urlp->vals, i, &val);
            return val;
        }
    }

    return def;
}
Пример #5
0
const char *
url_parser_get_parameter_value (url_parser_t *urlp, int idx)
{
    char *v;
    zarray_get(urlp->vals, idx, &v);
    return v;
}
Пример #6
0
int g2d_polygon_contains_point_ref(const zarray_t *poly, double q[2])
{
    // use winding. If the point is inside the polygon, we'll wrap
    // around it (accumulating 6.28 radians). If we're outside the
    // polygon, we'll accumulate zero.
    int psz = zarray_size(poly);

    double acc_theta = 0;

    double last_theta;

    for (int i = 0; i <= psz; i++) {
        double p[2];

        zarray_get(poly, i % psz, &p);

        double this_theta = atan2(q[1]-p[1], q[0]-p[0]);

        if (i != 0)
            acc_theta += mod2pi(this_theta - last_theta);

        last_theta = this_theta;
    }

    return acc_theta > M_PI;
}
Пример #7
0
	CameraHandler() {
		zarray_t* urls = image_source_enumerate();

		bool gotCamera = false;
		for (int i = 0; i < zarray_size(urls); ++i) {
			char* url;
			zarray_get(urls, i, &url);
			_isrc = image_source_open(url);
			if (_isrc != NULL) {
				printf("connected to camera %s\n", url);
				gotCamera = true;
				free(url);
				break;
			}
		}
		zarray_destroy(urls);
		if (!gotCamera) {
			printf("couldn't find a camera\n");
			exit(1);
		}

		if (pthread_mutex_init(&_dataMutex, NULL)) {
			printf("dataMutex not initialized\n");
			exit(1);
		}

		_im = nullptr;
		_running = false;
		_staticImage = false;
		_isrc->start(_isrc);
	}
Пример #8
0
int vx_gtk_display_dispatch_key(vx_display_t * disp, vx_key_event_t *event)
{
    assert(disp->impl_type == VX_GTK_DISPLAY_IMPL);
    state_t * state = disp->impl;

    // Process key shortcuts for the display
    pthread_mutex_lock(&state->mutex);

    int mouse_pressed_layer_id = state->mouse_pressed_layer_id; //local copy

    // Also dispatch to the relevant layers camera manager
    {
        layer_info_t * linfo = NULL;
        zhash_get(state->layer_info_map, &mouse_pressed_layer_id, &linfo);
        if (linfo != NULL) // sometimes there could be no layers
            linfo->event_handler->key_event(linfo->event_handler, NULL, event);
    }

    pthread_mutex_unlock(&state->mutex);


    pthread_mutex_lock(&state->listener_mutex);
    // notify all listeners of this event
    for (int i = 0; i < zarray_size(state->listeners); i++) {
        vx_display_listener_t * l = NULL;
        zarray_get(state->listeners, i, &l);
        l->event_dispatch_key(l, state->mouse_pressed_layer_id, event);
    }
    pthread_mutex_unlock(&state->listener_mutex);

    return 1; // gobble all events
}
Пример #9
0
static void do_quad_task(void *p)
{
    struct quad_task *task = (struct quad_task*) p;

    zarray_t *clusters = task->clusters;
    zarray_t *quads = task->quads;
    apriltag_detector_t *td = task->td;
    int w = task->w, h = task->h;

    for (int cidx = task->cidx0; cidx < task->cidx1; cidx++) {

        zarray_t *cluster;
        zarray_get(clusters, cidx, &cluster);

        if (zarray_size(cluster) < td->qtp.min_cluster_pixels)
            continue;

        // a cluster should contain only boundary points around the
        // tag. it cannot be bigger than the whole screen. (Reject
        // large connected blobs that will be prohibitively slow to
        // fit quads to.)
        if (zarray_size(cluster) > 4*(w+h)) {
            continue;
        }

        struct quad quad;
        memset(&quad, 0, sizeof(struct quad));

        if (fit_quad(td, task->im, cluster, &quad)) {
            pthread_mutex_lock(&td->mutex);
            zarray_add(quads, &quad);
            pthread_mutex_unlock(&td->mutex);
        }
    }
}
Пример #10
0
void reset_locs(zarray_t* locs)
{
    for(int i = 0; i < zarray_size(locs); i++) {
        loc_t* tmp;
        zarray_get(locs, i, &tmp);
        tmp->valid = 0;
    }
}
Пример #11
0
void add_arr_of_locs_to_buffer(zarray_t* arr, vx_buffer_t* buf, double size, 
                                const float* color, metrics_t met)
{
    for(int i = 0; i < zarray_size(arr); i++)
    {
        loc_t* tmp;
        zarray_get(arr, i, &tmp);
        add_circle_to_buffer(buf, size, *tmp, color);
    }
}
Пример #12
0
static void notify_listeners_send_resources(vx_world_t * world, zhash_t * new_resources)
{
    pthread_mutex_lock(&world->listener_mutex);
    for (int i = 0; i < zarray_size(world->listeners); i++) {
        vx_world_listener_t * listener = NULL;
        zarray_get(world->listeners, i, &listener);
        listener->send_resources(listener, new_resources);
    }
    pthread_mutex_unlock(&world->listener_mutex);
}
Пример #13
0
static void notify_listeners_codes(vx_world_t * world, vx_code_output_stream_t * couts)
{
    pthread_mutex_lock(&world->listener_mutex);
    for (int i = 0; i < zarray_size(world->listeners); i++) {
        vx_world_listener_t * listener = NULL;
        zarray_get(world->listeners, i, &listener);
        listener->send_codes(listener, couts->data, couts->pos);
    }
    pthread_mutex_unlock(&world->listener_mutex);
}
Пример #14
0
void g2d_polygon_make_ccw(zarray_t *poly)
{
    // Step one: we want the points in counter-clockwise order.
    // If the points are in clockwise order, we'll reverse them.
    double total_theta = 0;
    double last_theta = 0;

    // Count the angle accumulated going around the polygon. If
    // the sum is +2pi, it's CCW. Otherwise, we'll get -2pi.
    int sz = zarray_size(poly);

    for (int i = 0; i <= sz; i++) {
        double p0[2], p1[2];
        zarray_get(poly, i % sz, &p0);
        zarray_get(poly, (i+1) % sz, &p1);

        double this_theta = atan2(p1[1]-p0[1], p1[0]-p0[0]);

        if (i > 0) {
            double dtheta = mod2pi(this_theta-last_theta);
            total_theta += dtheta;
        }

        last_theta = this_theta;
    }

    int ccw = (total_theta > 0);

    // reverse order if necessary.
    if (!ccw) {
        for (int i = 0; i < sz / 2; i++) {
            double a[2], b[2];

            zarray_get(poly, i, a);
            zarray_get(poly, sz-1-i, b);
            zarray_set(poly, i, b, NULL);
            zarray_set(poly, sz-1-i, a, NULL);
        }
    }
}
Пример #15
0
// does polya completely contain polyb?
int g2d_polygon_contains_polygon(const zarray_t *polya, const zarray_t *polyb)
{
    // do any of the line segments collide? If so, the answer is no.
    if (g2d_polygon_intersects_polygon(polya, polyb))
        return 0;

    // if none of the edges cross, then the polygon is either fully
    // contained or fully outside.
    double p[2];
    zarray_get(polyb, 0, p);

    return g2d_polygon_contains_point(polya, p);
}
Пример #16
0
// returns the layer under the specified x,y. Must be externally synchronized
static int pick_layer(render_info_t * rinfo, float x, float y)
{

    int layer_under_mouse_id = 0;
    for (int i = 0; i < zarray_size(rinfo->layers); i++) {
        layer_info_t * linfo = NULL;
        zarray_get(rinfo->layers, i, &linfo);
        int * viewport = NULL;
        zhash_get(rinfo->layer_positions, &linfo->layer_id, &viewport);
        if (check_viewport_bounds(x, y, viewport))
            layer_under_mouse_id = linfo->layer_id; // highest ranked layer that matches will be it
    }
    return layer_under_mouse_id;
}
Пример #17
0
    std::vector<TagMatch> detectTags(image_u8_t *im) {

        const int hamm_hist_max = 10;

        int hamm_hist[hamm_hist_max];
        memset(hamm_hist, 0, sizeof(hamm_hist));
        zarray_t *detections = apriltag_detector_detect(td, im);

        std::vector<TagMatch> tag_matches;
        for (int i = 0; i < zarray_size(detections); i++) {
            apriltag_detection_t *det;
            zarray_get(detections, i, &det);

            if (!quiet) {
                printf("detection %3d: id (%2dx%2d)-%-4d, hamming %d, goodness %8.3f, margin %8.3f\n",
                       i, det->family->d*det->family->d, det->family->h, det->id, det->hamming, det->goodness, det->decision_margin);
                // image_u8_draw_line(im, det->p[x][0], det->p[x][1], det->p[x+1][0], det->p[x+1][1], 255, 10);
            }

            if (tag_id == -1 || det->id == tag_id) {
                TagMatch tag_match;
                tag_match.id = det->family->d*det->family->d;
                tag_match.p0 = cv::Point2d(det->p[0][0], det->p[0][1]);
                tag_match.p1 = cv::Point2d(det->p[1][0], det->p[1][1]);
                tag_match.p2 = cv::Point2d(det->p[2][0], det->p[2][1]);
                tag_match.p3 = cv::Point2d(det->p[3][0], det->p[3][1]);

                Eigen::Map<Eigen::Matrix3d> H_map(det->H->data);
                tag_match.H = H_map.transpose();
                tag_matches.push_back(tag_match);
            }

            hamm_hist[det->hamming]++;
        }

        apriltag_detections_destroy(detections);

        if (!quiet) {
            timeprofile_display(td->tp);
            printf("nedges: %d, nsegments: %d, nquads: %d\n", td->nedges, td->nsegments, td->nquads);
            printf("Hamming histogram: ");
            for (int i = 0; i < hamm_hist_max; i++)
                printf("%5d", hamm_hist[i]);
            printf("%12.3f", timeprofile_total_utime(td->tp) / 1.0E3);
            printf("\n");
        }
        
        return tag_matches;
    }
Пример #18
0
// Do a quick swap:
void vx_buffer_swap(vx_buffer_t * buffer)
{
    pthread_mutex_lock(&buffer->mutex);
    {
        // It's possible that the serialization is running behind,
        // and may not have already serialized the pending_objs
        // In that case, they are discarded here, momentarily blocking
        // the calling thread.
        if (zarray_size(buffer->pending_objs) > 0) {
            // *+*+ corresponding decrement (if falling behind)
            zarray_vmap(buffer->pending_objs, vx_object_dec_destroy);
            zarray_clear(buffer->pending_objs);
            static int once = 1;
            if (once) {
                once = 0;
                printf("NFO: World serialization fell behind\n");
            }
        }

        // swap
        zarray_t * tmp = buffer->pending_objs;
        buffer->pending_objs = buffer->back_objs;
        buffer->back_objs = tmp;
    }
    pthread_mutex_unlock(&buffer->mutex);

    // Now flag a swap on the serialization thread
    pthread_mutex_lock(&buffer->world->queue_mutex);
    {
        // Ensure that the string is already in the queue, or add it if
        // it isn't. Duplicates are prohibited
        int index = -1;
        for (int i = 0, sz = zarray_size(buffer->world->buffer_queue); i < sz; i++) {
            char * test = NULL;
            zarray_get(buffer->world->buffer_queue, i, &test);

            if (strcmp(test, buffer->name) == 0) {
                index = i;
                break;
            }
        }
        if (index < 0) {
            zarray_add(buffer->world->buffer_queue, &buffer->name);
            pthread_cond_signal(&buffer->world->queue_cond);
        }
    }
    pthread_mutex_unlock(&buffer->world->queue_mutex);

}
Пример #19
0
void project_measurements_through_homography(matd_t* H, vx_buffer_t* buf,
        zarray_t* pix_found, int size)
{
    int npoints = NUM_CHART_BLOBS * 2;          //  line per chart blob
    float points[npoints*3];

    float* real_world_coords;
    if(size == NUM_TARGETS) real_world_coords = target_coords;
    else if(size == NUM_CHART_BLOBS) real_world_coords = chart_coords;
    else assert(0);

    for(int i = 0; i < size; i++) {
        // run each real world point through homography and add to buf
        
        double tmp[3] = {real_world_coords[i*2], real_world_coords[i*2+1], 1};
        matd_t* xy_matrix = matd_create_data(3,1,tmp);
        matd_t* pix_estimated = matd_op("(M)*M",H, xy_matrix);
        MATD_EL(pix_estimated,0,0) /= MATD_EL(pix_estimated,2, 0);
        MATD_EL(pix_estimated,1,0) /= MATD_EL(pix_estimated,2, 0);
        
        vx_buffer_add_back(buf,
                 vxo_pix_coords(VX_ORIGIN_BOTTOM_LEFT,
                        vxo_chain(vxo_mat_translate3(MATD_EL(pix_estimated,0,0), MATD_EL(pix_estimated,1,0), 0),
                            vxo_mat_scale(2.0),
                            vxo_circle(vxo_mesh_style(vx_green)))));

        // create endpoints for lines
        loc_t pos;
        zarray_get(pix_found, i, &pos); //     

        points[6*i + 0] = pos.x;
        points[6*i + 1] = pos.y;
        points[6*i + 2] = 0;
        points[6*i + 3] = MATD_EL(pix_estimated,0,0);
        points[6*i + 4] = MATD_EL(pix_estimated,1,0);
        points[6*i + 5] = 0;
    }

    // make lines
    vx_resc_t *verts = vx_resc_copyf(points, npoints*3);
    vx_buffer_add_back(buf, vxo_pix_coords(VX_ORIGIN_BOTTOM_LEFT,
                                    vxo_lines(verts, npoints, GL_LINES, 
                                        vxo_points_style(vx_blue, 2.0f))));
}
Пример #20
0
line_t find_line_endpoints(zarray_t* loc_arr, loc_t* p1, loc_t* p2)
{
    double largest_dist = INT_MIN;
    loc_t largest_loc = {-1, -1};
    double smallest_dist = INT_MAX;
    loc_t smallest_loc = {-1, -1};

    double slope = get_slope(*p1, *p2, 0, 0,  NULL);
    // find point on line to compare every node to, simple solution = set x = im->width/2
    loc_t* Q = p1;
    // get line unit vector,  y=mx+b  --> vector = (1,m)
    double mag = sqrt(1 + slope*slope);
    vec_t u = {1/mag, slope/mag};
    // assert(sqrt((u.x*u.x) + (u.y*u.y)) == 1);       // length of u should be 1
    // printf("\nunit vec:(%lf(%lf), %lf)  Point(%d, %d)\n", u.x, 1/mag, u.y, Q.x, Q.y);
    for(int i = 0; i < zarray_size(loc_arr); i++)
    {   
        loc_t* tmp;
        zarray_get(loc_arr, i, &tmp);

        // find the projection of point onto line
        vec_t QP = {Q->x - tmp->x, Q->y - tmp->y};
        double dist = u.x * QP.x  +  u.y * QP.y; 

        // printf("dist:%lf  small:%lf  larg:%lf   QP:(%lf, %lf)  loc:(%d, %d) \n", 
        //        dist, smallest_dist, largest_dist, QP.x, QP.y, node->loc.x, node->loc.y);
        if(dist < smallest_dist) {
            smallest_dist = dist;
            smallest_loc.x = tmp->x;
            smallest_loc.y = tmp->y;
        }
        if(dist > largest_dist) {
            largest_dist = dist;
            largest_loc.x = tmp->x;
            largest_loc.y = tmp->y;
        }
    }

    line_t ret = {  .end = largest_loc,
                    .start = smallest_loc,
                    .nodes = NULL };
    return(ret);
}
Пример #21
0
// XXX make static
render_info_t * render_info_copy (render_info_t * rinfo)
{
    assert(rinfo != NULL);
    render_info_t * rinfo_copy = render_info_create();

    // copy a list of ints (ordered)
    for (int i = 0; i < zarray_size(rinfo->layers); i++) {
        layer_info_t * layer_info = NULL;
        zarray_get(rinfo->layers, i, &layer_info);
        zarray_add(rinfo_copy->layers, &layer_info);
    }

    // copy all the camera positions
    {
        zhash_iterator_t vit;
        uint32_t layer_id;
        vx_camera_pos_t *pos;
        zhash_iterator_init (rinfo->camera_positions, &vit);
        while (zhash_iterator_next (&vit, &layer_id, &pos)) {
            vx_camera_pos_t *pos_copy = malloc (sizeof(*pos_copy));
            memcpy(pos_copy, pos, sizeof(vx_camera_pos_t));
            zhash_put (rinfo_copy->camera_positions, &layer_id, &pos_copy, NULL, NULL);
        }
    }

    // copy each individual layer viewports
    {
        zhash_iterator_t itr;
        uint32_t layer_id;
        int *viewport;
        zhash_iterator_init (rinfo->layer_positions, &itr);
        while (zhash_iterator_next (&itr, &layer_id, &viewport)) {
            int *viewport_copy = malloc (4*sizeof(int));
            memcpy(viewport_copy, viewport, 4*sizeof(int));
            zhash_put (rinfo_copy->layer_positions, &layer_id, &viewport_copy, NULL, NULL);
        }
    }

    memcpy(rinfo_copy->viewport, rinfo->viewport, 4*sizeof(int));

    return rinfo_copy;
}
Пример #22
0
static void print_bounds(zarray_t * vertices)
{
    // Approximate centroid: Just average all vertices, regardless of
    // the frequency they are referenced by an index
    float minMax[3][2] = {{FLT_MAX,-FLT_MAX},{FLT_MAX,-FLT_MAX},{FLT_MAX,-FLT_MAX}};
    for (int i = 0; i < zarray_size(vertices); i++) {
        float pt[3];
        zarray_get(vertices, i, &pt);

        // iterate over xyz coords
        for (int j = 0; j < 3; j++) {
            minMax[j][0] = fminf(pt[j], minMax[j][0]);
            minMax[j][1] = fmaxf(pt[j], minMax[j][1]);
        }
    }

    printf(" Object bounds: xyz [%.2f, %.2f][%.2f, %.2f][%.2f, %.2f]\n",
           minMax[0][0],minMax[0][1],
           minMax[1][0],minMax[1][1],
           minMax[2][0],minMax[2][1]);
}
Пример #23
0
int main(int argc, char *argv[])
{
    getopt_t *getopt = getopt_create();

    getopt_add_bool(getopt, 'h', "help", 0, "Show this help");
    getopt_add_bool(getopt, 'd', "debug", 0, "Enable debugging output (slow)");
    getopt_add_bool(getopt, 'q', "quiet", 0, "Reduce output");
    getopt_add_string(getopt, 'f', "family", "tag36h11", "Tag family to use");
    getopt_add_int(getopt, '\0', "border", "1", "Set tag family border size");
    getopt_add_int(getopt, 'i', "iters", "1", "Repeat processing on input set this many times");
    getopt_add_int(getopt, 't', "threads", "4", "Use this many CPU threads");
    getopt_add_double(getopt, 'x', "decimate", "1.0", "Decimate input image by this factor");
    getopt_add_double(getopt, 'b', "blur", "0.0", "Apply low-pass blur to input");
    getopt_add_bool(getopt, '1', "refine-decode", 0, "Spend more time trying to decode tags");
    getopt_add_bool(getopt, '2', "refine-pose", 0, "Spend more time trying to precisely localize tags");

    if (!getopt_parse(getopt, argc, argv, 1) || getopt_get_bool(getopt, "help")) {
        printf("Usage: %s [options] <input files>\n", argv[0]);
        getopt_do_usage(getopt);
        exit(0);
    }

    const zarray_t *inputs = getopt_get_extra_args(getopt);

    apriltag_family_t *tf = NULL;
    const char *famname = getopt_get_string(getopt, "family");
    if (!strcmp(famname, "tag36h11"))
        tf = tag36h11_create();
    else if (!strcmp(famname, "tag36h10"))
        tf = tag36h10_create();
    else if (!strcmp(famname, "tag36artoolkit"))
        tf = tag36artoolkit_create();
    else if (!strcmp(famname, "tag25h9"))
        tf = tag25h9_create();
    else if (!strcmp(famname, "tag25h7"))
        tf = tag25h7_create();
    else {
        printf("Unrecognized tag family name. Use e.g. \"tag36h11\".\n");
        exit(-1);
    }

    tf->black_border = getopt_get_int(getopt, "border");

    apriltag_detector_t *td = apriltag_detector_create();
    apriltag_detector_add_family(td, tf);
    td->quad_decimate = getopt_get_double(getopt, "decimate");
    td->quad_sigma = getopt_get_double(getopt, "blur");
    td->nthreads = getopt_get_int(getopt, "threads");
    td->debug = getopt_get_bool(getopt, "debug");
    td->refine_decode = getopt_get_bool(getopt, "refine-decode");
    td->refine_pose = getopt_get_bool(getopt, "refine-pose");

    int quiet = getopt_get_bool(getopt, "quiet");

    int maxiters = getopt_get_int(getopt, "iters");

    const int hamm_hist_max = 10;

    for (int iter = 0; iter < maxiters; iter++) {

        if (maxiters > 1)
            printf("iter %d / %d\n", iter + 1, maxiters);

        for (int input = 0; input < zarray_size(inputs); input++) {

            int hamm_hist[hamm_hist_max];
            memset(hamm_hist, 0, sizeof(hamm_hist));

            char *path;
            zarray_get(inputs, input, &path);
            if (!quiet)
                printf("loading %s\n", path);

            image_u8_t *im = image_u8_create_from_pnm(path);
            if (im == NULL) {
                printf("couldn't find %s\n", path);
                continue;
            }

            zarray_t *detections = apriltag_detector_detect(td, im);

            for (int i = 0; i < zarray_size(detections); i++) {
                apriltag_detection_t *det;
                zarray_get(detections, i, &det);

                if (!quiet)
                    printf("detection %3d: id (%2dx%2d)-%-4d, hamming %d, goodness %8.3f, margin %8.3f\n",
                           i, det->family->d*det->family->d, det->family->h, det->id, det->hamming, det->goodness, det->decision_margin);

                hamm_hist[det->hamming]++;

                apriltag_detection_destroy(det);
            }

            zarray_destroy(detections);


            if (!quiet) {
                timeprofile_display(td->tp);
                printf("nedges: %d, nsegments: %d, nquads: %d\n", td->nedges, td->nsegments, td->nquads);
            }

            if (!quiet)
                printf("Hamming histogram: ");

            for (int i = 0; i < hamm_hist_max; i++)
                printf("%5d", hamm_hist[i]);

            if (quiet) {
                printf("%12.3f", timeprofile_total_utime(td->tp) / 1.0E3);
            }

            printf("\n");

            image_u8_destroy(im);
        }
    }

    // don't deallocate contents of inputs; those are the argv
    apriltag_detector_destroy(td);

    tag36h11_destroy(tf);
    return 0;
}
int main(){
  
  bool showGradient = true;
  bool found = false;

  VideoCapture cap(0); // open the default camera
  Size size(854,480);  // size of desired frame origionally 1280x720, 1024x576, 854x480
  if(!cap.isOpened())  // check if camera opened
    return -1;
  
  Mat frame;
  Mat src;
  
  /* From apriltag_demo.c */
  
  int maxiters = 5;
  const int hamm_hist_max = 10;
  int quiet = 0;
  
  apriltag_family_t *tf = tag36h11_create();                // Apriltag family 36h11, can change
  tf->black_border = 1;                                     // Set tag family border size
  
  apriltag_detector_t *td = apriltag_detector_create();     // Apriltag detector
  apriltag_detector_add_family(td, tf);                     // Add apriltag family
  
  td->quad_decimate = 1.0;                                  // Decimate input image by factor
  td->quad_sigma = 0.0;                                     // No blur (I think)
  td->nthreads = 4;                                         // 4 treads provided
  td->debug = 0;                                            // No debuging output
  td->refine_decode = 0;                                    // Don't refine decode
  td->refine_pose = 0;                                      // Don't refine pose
  
  // Output variables
  char imgSize[20];
  char renderTime[20];
  char detectString[50];
  char convertTime[50];
  char displayString[120];
  char outputString[120];
  char locationString[120];
  double time_taken = 0.0;
  
  long double totalFPS = 0.0;
  double count = 0.0;
  
  /* End of apriltag_demo.c */
  
  while(1){
    
    clock_t t;
    t = clock();
    
    cap >> src;                                               // Get a new frame from camera
    if(found){ resize(src,frame,size); }                      // Resize to smaller image if tag found
    else{ frame = src; }                                      // Keep standard image if no tag
    
    if(showGradient){
      cvtColor(src, frame, CV_BGR2GRAY);
      cvtColor(frame, frame, CV_GRAY2RGB);
      src = gradientEdges(frame);                               // Show gradient for fun
    }else{
      cvtColor(src, src, CV_BGR2GRAY);
    }
    
    pnm_t *pnm = mat2pnm(&frame);                             // Convert Mat fram to pnm
    image_u8_t *im = pnm_to_image_u8(pnm);                    // Convert pnm to gray image_u8
    if (im == NULL) {                                         // Error - no image created from pnm
      std::cout << "Error, not a proper pnm" << std::endl;
      return -1;
    }
    
    /*** Start from origional Apriltags from apriltag_demo.c ***/

    int hamm_hist[hamm_hist_max];
    memset(hamm_hist, 0, sizeof(hamm_hist));
    zarray_t *detections = apriltag_detector_detect(td, im);
    
    for (int i = 0; i < zarray_size(detections); i++) {
      
      apriltag_detection_t *det;
      zarray_get(detections, i, &det);
      sprintf(locationString, "Tag Center: (%f,%f)", det->c[0], det->c[1]);
      sprintf(detectString, "detection %2d: id (%2dx%2d)-%-4d, hamming %d, goodness %5.3f, margin %5.3f\n",
               i+1, det->family->d*det->family->d, det->family->h, det->id, det->hamming, det->goodness, det->decision_margin);

      hamm_hist[det->hamming]++;
      
      // draws a vertical rectangle around tag, not ideal, but easy to implement
      // det->p[corner][positon], counter clockwise
      Point pt1 = Point(det->p[0][0], det->p[0][1]);
      Point pt2 = Point(det->p[2][0], det->p[2][1]);
      cv::rectangle(src, pt1, pt2, cvScalar(102,255,0));
      
      apriltag_detection_destroy(det);
    }
    
    if(zarray_size(detections) < 1){
      found = false;
      sprintf(detectString, "No tag detected");
      sprintf(locationString, "No tag detected");
    }else{
      found = false;
    }
    
    zarray_destroy(detections);
    image_u8_destroy(im);

    t = clock() - t;
    double time_taken = ((double)t)/(CLOCKS_PER_SEC/1000);
    //printf("ms to render: %5.3f\n", time_taken);
    
    if (!quiet) {
      //timeprofile_display(td->tp);
      totalFPS += (1000.0/time_taken);
      count += 1.0;
      if(count > 30000.0){
        totalFPS = 0.0;
        count = 0.0;
      }
      sprintf(displayString, "fps: %2.2Lf, nquads: %d",totalFPS/count, td->nquads);
      //std::cout << displayString;
    }
    
    //for (int i = 0; i < hamm_hist_max; i++)
      //printf("%5d", hamm_hist[i]);
    
    sprintf(renderTime, "Render: %5.3fms", time_taken);
    sprintf(imgSize, "%dx%d", frame.cols, frame.rows);
    sprintf(outputString, "%s %s %s", renderTime, convertTime, imgSize);
    printf("%s %s\r", detectString, outputString);
    
    if (quiet) {
      printf("%12.3f", timeprofile_total_utime(td->tp) / 1.0E3);
    }
    
    printf("\n");
    
    /*** End of origional Apriltags from apriltag_demo.c ***/
    
    // displays fps, edges, segments, quads
    putText(src, displayString, cvPoint(30,30),
            FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(150,150,250), 1, CV_AA);
    
    // displays render time, convert time, and image size
    putText(src, outputString, cvPoint(30,50),
            FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(150,150,250), 1, CV_AA);
    
    // Displays any detections (if any)
    putText(src, detectString, cvPoint(30,70),
            FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(150,150,250), 1, CV_AA);
    
    // Displays tag location (if any)
    putText(src, locationString, cvPoint(30,90),
            FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(150,150,250), 1, CV_AA);
    
    imshow("Display Apriltags", src);
    
    if(waitKey(30) >= 0) break;
  }
  
  /* deallocate apriltag constructs */
  apriltag_detector_destroy(td);
  tag36h11_destroy(tf);
  
  return 0;
}
Пример #25
0
static void * movie_run(void * params)
{
    state_t * state = params;

    zarray_t * frames = zarray_create(sizeof(movie_frame_t*));

    char * last_filename = NULL;
    char * current_filename = NULL;

    gzFile gzMovie = NULL;
    int movie_frames = 0;
    int lost_frames = 0;
    uint64_t movie_start_mtime = 0;

    while (state->rendering) {


        pthread_mutex_lock(&state->movie_mutex);
        while (state->rendering && current_filename == state->movie_file && zarray_size(state->movie_pending) == 0)
            pthread_cond_wait(&state->movie_cond, &state->movie_mutex);

        if (!state->rendering) // exit signaled while waiting on cond
            break;

        for (int i = 0; i < zarray_size(state->movie_pending); i++) {
            movie_frame_t * tmp = NULL;
            zarray_get(state->movie_pending, i, &tmp);
            zarray_add(frames, &tmp);
        }
        zarray_clear(state->movie_pending);
        current_filename = state->movie_file;

        pthread_mutex_unlock(&state->movie_mutex);


        // Depending on setup, execute different actions
        // 1) Open 2) Close 3) Write a frame

        if (zarray_size(frames) > 0 && current_filename != NULL) {

            // Write the most recent frame, dump the rest
            movie_frame_t * movie_img = NULL;
            zarray_get(frames, zarray_size(frames)-1, &movie_img);
            zarray_remove_index(frames, zarray_size(frames)-1, 0);

            char header[256];
            sprintf(header, "#mtime=%"PRIu64"\nP6 %d %d %d\n", movie_img->mtime, movie_img->width, movie_img->height, 255);
            int header_len = strlen(header);
            int imglen = movie_img->stride*movie_img->height;// RGB format

            gzwrite(gzMovie, header, header_len);
            gzwrite(gzMovie, movie_img->buf, imglen);
            int res = gzflush(gzMovie, Z_SYNC_FLUSH);

            if (res != Z_OK) {
                int errval = 0;
                printf("Error writing movie %s. Closing file\n", gzerror(gzMovie, &errval));
                gzclose(gzMovie);
                free(current_filename);
                current_filename = NULL;
            }
            movie_frames++;
            movie_frame_destroy (movie_img);
        }
        // cleanup the frames:
        lost_frames += zarray_size(frames);
        zarray_vmap(frames, movie_frame_destroy);
        zarray_clear(frames);


        // Got a new filename, need to start recording
        if (current_filename != NULL && last_filename == NULL)
        {

            gzMovie = gzopen(current_filename, "w3");
            movie_frames = 0;
            lost_frames = 0;
            movie_start_mtime = vx_mtime();

            printf("NFO: Starting movie at %s\n", current_filename);

            if (gzMovie == NULL) {
                printf("WRN: Unable to start movie at %s\n", current_filename);
                free(current_filename); // XXX Would need to edit
                                        // state->movie_file ?
                current_filename = NULL;
            }
        }


        if (current_filename == NULL && last_filename != NULL)
        {

            gzclose(gzMovie);

            printf("NFO: Wrote/lost %d/%d movie frames at %.2f fps to %s\n",
                   movie_frames, lost_frames, 1e3 * movie_frames / (vx_mtime() - movie_start_mtime), last_filename);

            free(last_filename);
        }


        last_filename = current_filename;
    }

    // XXX Cleanup? might shutdown while recording?

    return NULL;
}
Пример #26
0
// Pass in a codes describing which resources are no longer in use. Decrement user counts,
// and return a list of all resources whos counts have reached zero, which therefore
// should be deleted from the display using a OP_DEALLOC_RESOURCES opcode
void vx_resc_manager_buffer_resources(vx_resc_manager_t * mgr, const uint8_t * data, int datalen)
{
    if (0) print_manager(mgr);

    vx_code_input_stream_t * cins = vx_code_input_stream_create(data, datalen);
    int code = cins->read_uint32(cins);
    assert(code == OP_BUFFER_RESOURCES);
    int worldID = cins->read_uint32(cins);
    char * name = strdup(cins->read_str(cins)); //freed when cur_resources is eventually removed from the buffer map
    int count = cins->read_uint32(cins);

    zhash_t * cur_resources = zhash_create(sizeof(uint64_t), sizeof(vx_resc_t*), zhash_uint64_hash, zhash_uint64_equals);
    vx_resc_t * vr = NULL;
    for (int i = 0; i < count; i++) {
        uint64_t id = cins->read_uint64(cins);
        zhash_put(cur_resources, &id, &vr, NULL, NULL);
    }
    assert(cins->pos == cins->len); // we've emptied the stream
    vx_code_input_stream_destroy(cins);

    // 1 Update our records
    zhash_t * worldBuffers = NULL;
    zhash_get(mgr->allLiveSets, &worldID, &worldBuffers);
    if (worldBuffers == NULL) {
        worldBuffers = zhash_create(sizeof(char*), sizeof(zhash_t*), zhash_str_hash, zhash_str_equals);
        zhash_put(mgr->allLiveSets, &worldID, &worldBuffers, NULL, NULL);
    }

    zhash_t * old_resources = NULL;
    char * old_name = NULL;
    zhash_put(worldBuffers, &name, &cur_resources, &old_name, &old_resources);
    free(old_name);

    // 2 Figure out which resources have become unused:
    if(old_resources != NULL) {
        removeAll(old_resources, cur_resources);

        zarray_t * dealloc = zarray_create(sizeof(uint64_t));

        // now 'old_resources' contains only the resources that are no longer referenced
        // iterate through each one, and see if there is a buffer somewhere that references it
        zhash_iterator_t prev_itr;
        zhash_iterator_init(old_resources, &prev_itr);
        uint64_t id = -1;
        vx_resc_t * vr = NULL;
        while(zhash_iterator_next(&prev_itr, &id, &vr)) {
            // Check all worlds
            zhash_iterator_t  world_itr;// gives us all worlds
            zhash_iterator_init(mgr->allLiveSets, &world_itr);
            uint32_t wIDl = -1;
            zhash_t * buffer_map = NULL;
            while(zhash_iterator_next(&world_itr, &wIDl, &buffer_map)) {
                zhash_iterator_t buffer_itr; // gives us all buffers
                zhash_iterator_init(buffer_map, &buffer_itr);
                char * bName = NULL;
                zhash_t * resc_map = NULL;
                while(zhash_iterator_next(&buffer_itr, &bName, &resc_map)) {
                    if (zhash_contains(resc_map, &id)) {
                        goto continue_outer_loop;
                    }
                }

            }

            // If none of the worlds have this resource, we need to flag removal
            zarray_add(dealloc, &id);

          continue_outer_loop:
            ;
        }


        // 3 Issue dealloc commands
        if (zarray_size(dealloc) > 0) {
            vx_code_output_stream_t * couts = vx_code_output_stream_create(512);
            couts->write_uint32(couts, OP_DEALLOC_RESOURCES);
            couts->write_uint32(couts, zarray_size(dealloc));
            for (int i = 0; i < zarray_size(dealloc); i++) {
                uint64_t id = 0;
                zarray_get(dealloc, i, &id);
                couts->write_uint64(couts, id);
            }

            mgr->disp->send_codes(mgr->disp, couts->data, couts->pos);

            vx_code_output_stream_destroy(couts);

            // Also remove the resources we deallocated from remoteResc
            for (int i = 0; i < zarray_size(dealloc); i++) {
                uint64_t id = 0;
                zarray_get(dealloc, i, &id);

                assert(zhash_contains(mgr->remoteResc, &id));
                zhash_remove(mgr->remoteResc, &id, NULL, NULL);
            }

        }
        zarray_destroy(dealloc);
        zhash_destroy(old_resources);

    }
    if (0) {
        print_manager(mgr);
        printf("\n\n");
    }
}
Пример #27
0
static void update_view(vx_gtk_buffer_manager_t * gtk)
{
    // This order of these two mutex locks should prevent deadloc
    // even if a user sends op codes while the user holds the GDK mutex
    gdk_threads_enter();
    pthread_mutex_lock(&gtk->mutex);

    // Clear XXX Double buffered?
    GList * children = gtk_container_get_children(GTK_CONTAINER(gtk->window));
    for(GList * iter = children; iter != NULL; iter = g_list_next(iter))
        gtk_widget_destroy(GTK_WIDGET(iter->data));
    g_list_free(children);

    // Rebuild from scratch
    GtkWidget * box = gtk_vbox_new(0, 10);
    GtkWidget * widget = NULL;

    zarray_t *layers = zhash_values(gtk->layers); // contents: layer_info_t*
    zarray_sort(layers, layer_info_compare);

    for (int lidx = 0; lidx < zarray_size(layers); lidx++) {

        layer_info_t *linfo = NULL;
        zarray_get(layers, lidx, &linfo);

        // Draw the layer name:
        widget = gtk_label_new("");
        char * text = sprintf_alloc("<b>Layer %d</b>", linfo->layer_id);
        gtk_label_set_markup(GTK_LABEL(widget), text);
        free(text);
        //gtk_container_add(GTK_CONTAINER(box), widget);
        gtk_box_pack_start(GTK_BOX(box), widget, FALSE, FALSE, 0);

        // Make a checkbox for each buffer
        zarray_t *buffers = zhash_values(linfo->buffers); // contents: buffer_info_t*
        zarray_sort(buffers, buffer_info_compare);

        for (int i = 0; i < zarray_size(buffers); i++) {

            buffer_info_t * buffer = NULL;
            zarray_get(buffers, i, &buffer);
            assert(buffer != NULL);

            widget = gtk_check_button_new_with_label(buffer->name);
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), buffer->enabled);
            g_signal_connect (G_OBJECT(widget), "toggled",
                              G_CALLBACK (buffer_checkbox_changed), buffer);
            //gtk_container_add(GTK_CONTAINER(box), widget);
            gtk_box_pack_start(GTK_BOX(box), widget, FALSE, FALSE, 0);
        }

        zarray_destroy(buffers);
    }
    gtk_container_add(GTK_CONTAINER(gtk->window), box);
    gtk_widget_show_all(box);

    zarray_destroy(layers);

    pthread_mutex_unlock(&gtk->mutex);
    gdk_threads_leave();
}
Пример #28
0
int main(int argc, char *argv[])
{
    april_tag_family_t *tf = tag36h11_create();

    april_tag_detector_t *td = april_tag_detector_create(tf);
    td->small_tag_refinement = 0;

    int maxiters = 1;

    zarray_t *inputs = zarray_create(sizeof(char*));
    int waitsec = 0;

    for (int i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "-d"))
            td->debug = 1;
        else if (!strcmp(argv[i], "-t"))
            td->nthreads = atoi(argv[++i]);
        else if (!strcmp(argv[i], "-f"))
            td->seg_decimate = (i+1 < argc && isdigit(argv[i+1][0])) ? atoi(argv[++i]) : 2;
        else if (!strcmp(argv[i], "-i"))
            maxiters = atoi(argv[++i]);
        else if (!strcmp(argv[i], "-r"))
            td->small_tag_refinement = 1;
        else if (!strcmp(argv[i], "-w"))
            waitsec = atoi(argv[++i]);
        else if (!strcmp(argv[i], "-b"))
            td->seg_sigma = atof(argv[++i]);
/*        else if (!strcmp(argv[i], "--family")) {
            char *fam = argv[++i];
            if (!strcmp(fam, "36h11"))
                td->tag_family = tag36h11_create();
            else if (!strcmp(fam, "36h10"))
                td->tag_family = tag36h10_create();
                } */
        else
            zarray_add(inputs, &argv[i]);
    }

    for (int iter = 0; iter < maxiters; iter++) {

        if (maxiters > 1)
            printf("iter %d / %d\n", iter + 1, maxiters);

        for (int input = 0; input < zarray_size(inputs); input++) {

            char *path;
            zarray_get(inputs, input, &path);
            printf("loading %s\n", path);
            image_u8_t *im = image_u8_create_from_pnm(path);
            if (im == NULL) {
                printf("couldn't find %s\n", path);
                continue;
            }

            zarray_t *detections = april_tag_detector_detect(td, im);

            for (int i = 0; i < zarray_size(detections); i++) {
                april_tag_detection_t *det;
                zarray_get(detections, i, &det);

                printf("detection %3d: id %4d, hamming %d, goodness %f\n", i, det->id, det->hamming, det->goodness);
                april_tag_detection_destroy(det);
            }

            zarray_destroy(detections);

            timeprofile_display(td->tp);
            printf("nedges: %d, nsegments: %d, nquads: %d\n", td->nedges, td->nsegments, td->nquads);

            image_u8_destroy(im);

            if (zarray_size(inputs) > 1 || iter > 0)
                sleep(waitsec);
        }
    }

    april_tag_detector_destroy(td);

    tag36h11_destroy(tf);
    return 0;
}
Пример #29
0
// returns 1 if no error
int
getopt_parse (getopt_t *gopt, int argc, char *argv[], int showErrors)
{
    int okay = 1;
    zarray_t *toks = zarray_create (sizeof(char*));

    // take the input stream and chop it up into tokens
    for (int i = 1; i < argc; i++) {
        char *arg = strdup (argv[i]);

        if (arg[0] != '-') {
            // if this isn't an option, put the whole thing in the args list.
            zarray_add (toks, &arg);

        }
        else {
            // this is an option. It could be a flag (like -v), or an option
            // with arguments (--file=foobar.txt).
            char *eq = strstr (arg, "=");

            // no equal sign? Push the whole thing.
            if (eq == NULL) {
                zarray_add (toks, &arg);
            }
            else {
                // there was an equal sign. Push the part
                // before and after the equal sign
                char *val = strdup (&eq[1]);
                eq[0] = 0;
                zarray_add (toks, &arg);

                // if the part after the equal sign is
                // enclosed by quotation marks, strip them.
                if (val[0]=='\"') {
                    int last = strlen (val) - 1;
                    if (val[last]=='\"')
                        val[last] = 0;
                    char *valclean = strdup (&val[1]);
                    zarray_add (toks, &valclean);
                    free (val);
                }
                else
                    zarray_add (toks, &val);
            }
        }
    }

    // now loop over the elements and evaluate the arguments
    unsigned int i = 0;

    char *tok = NULL;

    while (i < zarray_size (toks)) {

        // rather than free statement throughout this while loop
        if (tok != NULL)
            free (tok);

        zarray_get (toks, i, &tok);

        if (0==strncmp (tok,"--", 2)) {
            char *optname = &tok[2];
            getopt_option_t *goo = NULL;
            zhash_get (gopt->lopts, &optname, &goo);
            if (goo == NULL) {
                okay = 0;
                if (showErrors)
                    printf ("Unknown option --%s\n", optname);
                i++;
                continue;
            }

            goo->was_specified = 1;

            if (goo->type == GOO_BOOL_TYPE) {
                if ((i+1) < zarray_size (toks)) {
                    char *val = NULL;
                    zarray_get (toks, i+1, &val);

                    if (0==strcmp (val,"true")) {
                        i+=2;
                        getopt_modify_string (&goo->svalue, val);
                        continue;
                    }
                    if (0==strcmp (val,"false")) {
                        i+=2;
                        getopt_modify_string (&goo->svalue, val);
                        continue;
                    }
                }
                getopt_modify_string (&goo->svalue, strdup("true"));
                i++;
                continue;
            }

            if (goo->type == GOO_STRING_TYPE) {
                // TODO: check whether next argument is an option, denoting missing argument
                if ((i+1) < zarray_size (toks)) {
                    char *val = NULL;
                    zarray_get (toks, i+1, &val);
                    i+=2;
                    getopt_modify_string (&goo->svalue, val);
                    continue;
                }

                okay = 0;
                if (showErrors)
                    printf ("Option %s requires a string argument.\n",optname);
            }
        }

        if (0==strncmp (tok,"-",1) && strncmp (tok,"--",2)) {
            int len = strlen (tok);
            int pos;
            for (pos = 1; pos < len; pos++) {
                char sopt[2];
                sopt[0] = tok[pos];
                sopt[1] = 0;
                char *sopt_ptr = (char*) &sopt;
                getopt_option_t *goo = NULL;
                zhash_get (gopt->sopts, &sopt_ptr, &goo);

                if (goo==NULL) {
                    // is the argument a numerical literal that happens to be negative?
                    if (pos==1 && isdigit (tok[pos])) {
                        zarray_add (gopt->extraargs, &tok);
                        tok = NULL;
                        break;
                    }
                    else {
                        okay = 0;
                        if (showErrors)
                            printf ("Unknown option -%c\n", tok[pos]);
                        i++;
                        continue;
                    }
                }

                goo->was_specified = 1;

                if (goo->type == GOO_BOOL_TYPE) {
                    getopt_modify_string (&goo->svalue, strdup("true"));
                    continue;
                }

                if (goo->type == GOO_STRING_TYPE) {
                    if ((i+1) < zarray_size (toks)) {
                        char *val = NULL;
                        zarray_get (toks, i+1, &val);
                        // TODO: allow negative numerical values for short-name options ?
                        if (val[0]=='-')
                        {
                            okay = 0;
                            if (showErrors)
                                printf ("Ran out of arguments for option block %s\n", tok);
                        }
                        i++;
                        getopt_modify_string (&goo->svalue, val);
                        continue;
                    }

                    okay = 0;
                    if (showErrors)
                        printf ("Option -%c requires a string argument.\n", tok[pos]);
                }
            }
            i++;
            continue;
        }

        // it's not an option-- it's an argument.
        zarray_add (gopt->extraargs, &tok);
        tok = NULL;
        i++;
    }
    if (tok != NULL)
        free (tok);

    zarray_destroy (toks);

    return okay;
}
Пример #30
0
static void save_scene(state_t * state, vx_code_input_stream_t * cins)
{
    char * filename = NULL;
    if (vx_code_input_stream_available(cins) > 0) {
        const char * f2 = cins->read_str(cins);
        filename = strdup(f2);
    } else { // generate a unique ID

        uint64_t mtime = vx_mtime();
        time_t now  = time(NULL);
        struct tm * now2 = localtime(&now);

        filename=sprintf_alloc("v%4d%02d%02d_%02d%02d%02d_%03d.vxs",
                               now2->tm_year + 1900,
                               now2->tm_mon + 1,
                               now2->tm_mday,
                               now2->tm_hour,
                               now2->tm_min,
                               now2->tm_sec,
                               (int)(mtime % 1000));
    }

    vx_code_output_stream_t * couts = vx_gl_renderer_serialize(state->glrend);

    // Append camera positions
    if (state->last_render_info != NULL) {
        render_info_t *rinfo = state->last_render_info;

        for (int i = 0; i <4; i++)
            couts->write_uint32(couts, rinfo->viewport[i]);

        couts->write_uint32(couts, zarray_size(rinfo->layers));
        for (int i = 0; i < zarray_size(rinfo->layers); i++) {
            layer_info_t * linfo = NULL;
            zarray_get(rinfo->layers, i, &linfo);

            couts->write_uint32(couts, linfo->layer_id);

            vx_camera_pos_t * pos = NULL;
            int * viewport = NULL;
            zhash_get(rinfo->camera_positions, &linfo->layer_id, &pos);
            zhash_get(rinfo->layer_positions, &linfo->layer_id, &viewport);

            vx_tcp_util_pack_camera_pos(pos, couts);


            for (int i = 0; i < 4; i++)
                couts->write_uint32(couts, viewport[i]);
        }
    }



    FILE * fp = fopen(filename, "w");
    fwrite(couts->data, sizeof(uint8_t), couts->pos, fp);
    fclose(fp);
    printf("Wrote %d bytes to %s\n", couts->pos, filename);

    vx_code_output_stream_destroy(couts);
    free(filename);

}