Exemple #1
0
static void vx_world_buffer_destroy(vx_buffer_t * buffer)
{
    vx_world_t * vw = buffer->world;

    pthread_mutex_lock(&vw->buffer_mutex);

    free(buffer->name);
    zarray_vmap(buffer->back_objs, vx_object_dec_destroy);
    zarray_destroy(buffer->back_objs);

    zarray_vmap(buffer->pending_objs, vx_object_dec_destroy);
    zarray_destroy(buffer->pending_objs);

    zarray_vmap(buffer->front_objs, vx_object_dec_destroy);
    zarray_destroy(buffer->front_objs);

    zhash_vmap_values(buffer->front_resc, vx_resc_dec_destroy);
    zhash_destroy(buffer->front_resc);

    vx_code_output_stream_destroy(buffer->front_codes);

    pthread_mutex_destroy(&buffer->mutex);
    free(buffer);

    pthread_mutex_unlock(&vw->buffer_mutex);
}
Exemple #2
0
void
url_parser_destroy (url_parser_t *urlp)
{
    free(urlp->protocol);
    free(urlp->host);
    free(urlp->path);
    zarray_vmap(urlp->keys, free);
    zarray_vmap(urlp->vals, free);
    zarray_destroy(urlp->keys);
    zarray_destroy(urlp->vals);
    free(urlp);
}
Exemple #3
0
void vx_util_unproject(double * winxyz, double * model_matrix, double * projection_matrix, int * viewport, double * vec3_out)
{
    zarray_t * fp = zarray_create(sizeof(matd_t*));

    matd_t * mm = matd_create_data(4, 4, model_matrix);
    zarray_add(fp, &mm);
    matd_t * pm = matd_create_data(4, 4, projection_matrix);
    zarray_add(fp, &pm);

    matd_t *invpm = matd_op("(MM)^-1", pm, mm);
    zarray_add(fp, &invpm);

    double v[4] = { 2*(winxyz[0]-viewport[0]) / viewport[2] - 1,
                    2*(winxyz[1]-viewport[1]) / viewport[3] - 1,
                    2*winxyz[2] - 1,
                    1 };
    matd_t * vm = matd_create_data(4, 1, v);
    zarray_add(fp, &vm);

    matd_t * objxyzh = matd_op("MM", invpm, vm);
    zarray_add(fp, &objxyzh);

    vec3_out[0] = objxyzh->data[0] / objxyzh->data[3];
    vec3_out[1] = objxyzh->data[1] / objxyzh->data[3];
    vec3_out[2] = objxyzh->data[2] / objxyzh->data[3];

    // cleanup
    zarray_vmap(fp, matd_destroy);
    zarray_destroy(fp);
}
Exemple #4
0
void vx_util_project(double * xyz, double * M44, double * P44, int * viewport, double * win_out3)
{
    zarray_t * fp = zarray_create(sizeof(matd_t*));

    matd_t * M = matd_create_data(4,4, M44); zarray_add(fp, &M);
    matd_t * P = matd_create_data(4,4, P44); zarray_add(fp, &P);
    matd_t * xyzp = matd_create(4,1); zarray_add(fp, &xyzp);
    memcpy(xyzp->data, xyz, 3*sizeof(double));
    xyzp->data[3] = 1.0;

    matd_t * p = matd_op("MMM", P, M, xyzp); zarray_add(fp, &p);

        p->data[0] = p->data[0] / p->data[3];
        p->data[1] = p->data[1] / p->data[3];
        p->data[2] = p->data[2] / p->data[3];


    double res[] =  { viewport[0] + viewport[2]*(p->data[0]+1)/2.0,
                      viewport[1] + viewport[3]*(p->data[1]+1)/2.0,
                      (viewport[2] + 1)/2.0 };
    memcpy(win_out3, res, 3*sizeof(double));

    // cleanup
    zarray_vmap(fp, matd_destroy);
    zarray_destroy(fp);
}
Exemple #5
0
void default_cam_mgr_rotate(default_cam_mgr_t * state, double *q, uint32_t animate_ms)
{
    zarray_t * fp = zarray_create(sizeof(matd_t*));

    matd_t * eye = matd_create_data(3,1,state->eye1);       zarray_add(fp, &eye);
    matd_t *lookat = matd_create_data(3,1,state->lookat1);  zarray_add(fp, &lookat);
    matd_t *up = matd_create_data(3,1,state->up1);          zarray_add(fp, &up);


    matd_t * toEye = matd_subtract(eye, lookat); zarray_add(fp, &toEye);
    matd_t * nextToEye = matd_create(3,1); zarray_add(fp, &nextToEye);
    vx_util_quat_rotate(q, toEye->data, nextToEye->data);

    matd_t * nextEye = matd_add(lookat, nextToEye); zarray_add(fp, &nextEye);
    matd_t * nextUp = matd_copy(up); zarray_add(fp, &nextUp);

    vx_util_quat_rotate(q, up->data, nextUp->data);

    // copy back results
    memcpy(state->eye1, nextEye->data, sizeof(double)*3);
    memcpy(state->up1, nextUp->data, sizeof(double)*3);
    state->mtime1 = vx_util_mtime() + animate_ms;

    // Disable any prior fit command
    default_destroy_fit(state);

    // cleanup
    zarray_vmap(fp, matd_destroy);
    zarray_destroy(fp);

    default_cam_mgr_follow_disable(state);

}
void
getopt_destroy (getopt_t *gopt)
{
    // free the extra arguments and container
    zarray_vmap (gopt->extraargs, free);
    zarray_destroy (gopt->extraargs);

    // deep free of the getopt_option structs. Also frees key/values, so
    // after this loop, hash tables will no longer work
    zarray_vmap (gopt->options, getopt_option_destroy);
    zarray_destroy (gopt->options);

    // free tables
    zhash_destroy (gopt->lopts);
    zhash_destroy (gopt->sopts);

    free (gopt);
}
Exemple #7
0
void vx_util_lookat(double * _eye, double * _lookat, double * _up, double * _out44)
{
    zarray_t * fp = zarray_create(sizeof(matd_t*));

    matd_t * eye = matd_create_data(3,1, _eye);
    zarray_add(fp, &eye);

    matd_t * lookat = matd_create_data(3,1, _lookat);
    zarray_add(fp, &lookat);

    matd_t * up = matd_create_data(3,1, _up);
    zarray_add(fp, &up);

    up = matd_vec_normalize(up);

    zarray_add(fp, &up); // note different pointer than before!

    matd_t * tmp1 = matd_subtract(lookat, eye); zarray_add(fp, &tmp1);

    matd_t * f = matd_vec_normalize(tmp1);      zarray_add(fp, &f);
    matd_t * s = matd_crossproduct(f, up);      zarray_add(fp, &s);
    matd_t * u = matd_crossproduct(s, f);       zarray_add(fp, &u);

    matd_t * M = matd_create(4,4); // set the rows of M with s, u, -f
    zarray_add(fp, &M);
    memcpy(M->data,s->data,3*sizeof(double));
    memcpy(M->data + 4,u->data,3*sizeof(double));
    memcpy(M->data + 8,f->data,3*sizeof(double));
    for (int i = 0; i < 3; i++)
        M->data[2*4 +i] *= -1;
    M->data[3*4 + 3] = 1.0;


    matd_t * T = matd_create(4,4);
    T->data[0*4 + 3] = -eye->data[0];
    T->data[1*4 + 3] = -eye->data[1];
    T->data[2*4 + 3] = -eye->data[2];
    T->data[0*4 + 0] = 1;
    T->data[1*4 + 1] = 1;
    T->data[2*4 + 2] = 1;
    T->data[3*4 + 3] = 1;
    zarray_add(fp, &T);

    matd_t * MT = matd_op("MM",M,T);
    zarray_add(fp, &MT);


    memcpy(_out44, MT->data, 16*sizeof(double));

    // cleanup
    zarray_vmap(fp, matd_destroy);
    zarray_destroy(fp);
}
Exemple #8
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);

}
Exemple #9
0
void vx_util_angle_axis_to_quat(double theta, double * axis3, double * qout)
{
    zarray_t * fp = zarray_create(sizeof(matd_t*));

    matd_t * axis = matd_create_data(3,1, axis3); zarray_add(fp, &axis);
    matd_t * axis_norm = matd_vec_normalize(axis); zarray_add(fp, &axis_norm);

    qout[0] = cos(theta/2);
    double s = sin(theta/2);

    qout[1] = axis_norm->data[0] * s;
    qout[2] = axis_norm->data[1] * s;
    qout[3] = axis_norm->data[2] * s;

    // cleanup
    zarray_vmap(fp, matd_destroy);
    zarray_destroy(fp);
}
Exemple #10
0
vx_camera_pos_t * default_cam_mgr_get_cam_pos(default_cam_mgr_t * state, int * viewport, uint64_t mtime)
{
    vx_camera_pos_t * p = calloc(1, sizeof(vx_camera_pos_t));
    memcpy(p->viewport, viewport, 4*sizeof(int));

    p->perspective_fovy_degrees = state->perspective_fovy_degrees;
    p->zclip_near = state->zclip_near;
    p->zclip_far = state->zclip_far;

    // process a fit command if necessary:
    if (state->fit != NULL) {
        fit_t * f = state->fit;

        // consume the fit command
        state->fit = NULL; // XXX minor race condition, could lose a fit cmd

        // XXX We can probably do better than this using the viewport...
        state->lookat1[0] = (f->xy0[0] + f->xy1[0]) / 2;
        state->lookat1[1] = (f->xy0[1] + f->xy1[1]) / 2;
        state->lookat1[2] = 0;

        // dimensions of fit
        double Fw = f->xy1[0] - f->xy0[0];
        double Fh = f->xy1[1] - f->xy0[1];

        // aspect ratios
        double Far = Fw / Fh;
        double Var = p->viewport[2] * 1.0 / p->viewport[3];

        double tAngle = tan(p->perspective_fovy_degrees/2*M_PI/180.0);
        double height = fabs(0.5 * (Var > Far ? Fh : Fw / Var) / tAngle);

        state->eye1[0] = state->lookat1[0];
        state->eye1[1] = state->lookat1[1];
        state->eye1[2] = height;

        state->up1[0] = 0;
        state->up1[1] = 1;
        state->up1[2] = 0;

        state->mtime1 = f->mtime;

        free(f);
    }

    if (mtime > state->mtime1) {
        memcpy(p->eye, state->eye1, 3*sizeof(double));
        memcpy(p->up, state->up1, 3*sizeof(double));
        memcpy(p->lookat, state->lookat1, 3*sizeof(double));
        p->perspectiveness = state->perspectiveness1;
    } else  if (mtime <= state->mtime0) {
        memcpy(p->eye, state->eye0, 3*sizeof(double));
        memcpy(p->up, state->up0, 3*sizeof(double));
        memcpy(p->lookat, state->lookat0, 3*sizeof(double));
        p->perspectiveness = state->perspectiveness0;
    } else {
        double alpha1 = ((double) mtime - state->mtime0) / (state->mtime1 - state->mtime0);
        double alpha0 = 1.0 - alpha1;

        scaled_combination(state->eye0,    alpha0, state->eye1,    alpha1, p->eye,    3);
        scaled_combination(state->up0,     alpha0, state->up1,     alpha1, p->up,     3);
        scaled_combination(state->lookat0, alpha0, state->lookat1, alpha1, p->lookat, 3);
        p->perspectiveness = state->perspectiveness0*alpha0 + state->perspectiveness1*alpha1;

        // Tweak so eye-to-lookat is the right distance
        {
            zarray_t * fp = zarray_create(sizeof(matd_t*));

            matd_t * eye = matd_create_data(3,1, p->eye); zarray_add(fp, &eye);
            matd_t * lookat = matd_create_data(3,1, p->lookat); zarray_add(fp, &lookat);
            matd_t * up = matd_create_data(3,1, p->up); zarray_add(fp, &up);

            matd_t * eye0 = matd_create_data(3,1, state->eye0); zarray_add(fp, &eye0);
            matd_t * lookat0 = matd_create_data(3,1, state->lookat0); zarray_add(fp, &lookat0);
            matd_t * up0 = matd_create_data(3,1, state->up0); zarray_add(fp, &up0);

            matd_t * eye1 = matd_create_data(3,1, state->eye1); zarray_add(fp, &eye1);
            matd_t * lookat1 = matd_create_data(3,1, state->lookat1); zarray_add(fp, &lookat1);
            matd_t * up1 = matd_create_data(3,1, state->up1); zarray_add(fp, &up1);


            double dist0 = matd_vec_dist(eye0, lookat0);
            double dist1 = matd_vec_dist(eye1, lookat1);

            matd_t * dist = matd_create_scalar(dist0*alpha0 + dist1*alpha1); zarray_add(fp, &dist);

            matd_t * eye2p = matd_subtract(eye,lookat); zarray_add(fp, &eye2p);
            eye2p = matd_vec_normalize(eye2p); zarray_add(fp, &eye2p);

            eye = matd_op("M + (M*M)", lookat, eye2p, dist);

            // Only modified eye
            memcpy(p->eye, eye->data, 3*sizeof(double));

            zarray_vmap(fp, matd_destroy);

            zarray_destroy(fp);
        }
    }

    // Need to do more fixup depending on interface mode!
    {
        if (state->interface_mode <= 2.0) {
            // stack eye on lookat:
            p->eye[0] = p->lookat[0];
            p->eye[1] = p->lookat[1];
            p->lookat[2] = 0;

            // skip fabs() for ENU/NED compat
            //p->eye[2] = fabs(p->eye[2]);


            {
                matd_t * up = matd_create_data(3,1, p->up);
                up->data[2] = 0; // up should never point in Z
                matd_t * up_norm = matd_vec_normalize(up);

                memcpy(p->up, up_norm->data, sizeof(double)*3);
                matd_destroy(up);
                matd_destroy(up_norm);
            }

        } else if (state->interface_mode == 2.5) {
            zarray_t * fp = zarray_create(sizeof(matd_t*));

            matd_t * eye = matd_create_data(3,1, p->eye); zarray_add(fp, &eye);
            matd_t * lookat = matd_create_data(3,1, p->lookat); zarray_add(fp, &lookat);
            matd_t * up = matd_create_data(3,1, p->up); zarray_add(fp, &up);

            lookat->data[2] = 0.0;

            // Level horizon
            matd_t * dir = matd_subtract(lookat, eye); zarray_add(fp, &dir);
            matd_t * dir_norm = matd_vec_normalize(dir); zarray_add(fp, &dir_norm);
            matd_t * left = matd_crossproduct(up, dir_norm); zarray_add(fp, &left);
            left->data[2] = 0.0;

            left = matd_vec_normalize(left); zarray_add(fp, &left);


            // Don't allow upside down
            //up->data[2] = fmax(0.0, up->data[2]); // XXX NED?

            // Find an 'up' direction perpendicular to left
            matd_t * dot_scalar = matd_create_scalar(matd_vec_dot_product(up, left)); zarray_add(fp, &dot_scalar);
            up = matd_op("M - (M*M)", up,  left, dot_scalar); zarray_add(fp, &up);
            up = matd_vec_normalize(up); zarray_add(fp, &up);

            // Now find eye position by computing new lookat dir
            matd_t * eye_dir = matd_crossproduct(up, left); zarray_add(fp, &eye_dir);

            matd_t *eye_dist_scalar = matd_create_scalar(matd_vec_dist(eye, lookat)); zarray_add(fp, &eye_dist_scalar);

            eye = matd_op("M + (M*M)", lookat, eye_dir, eye_dist_scalar); zarray_add(fp, &eye);

            // export results back to p:
            memcpy(p->eye, eye->data, sizeof(double)*3);
            memcpy(p->lookat, lookat->data, sizeof(double)*3);
            memcpy(p->up, up->data, sizeof(double)*3);

            zarray_vmap(fp, matd_destroy);
            zarray_destroy(fp);
        }
    }

    // Fix up for bad zoom
    if (1) {
        matd_t * eye = matd_create_data(3,1, p->eye);
        matd_t * lookat = matd_create_data(3,1, p->lookat);
        matd_t * up = matd_create_data(3,1, p->up);

        matd_t * lookeye = matd_subtract(lookat, eye);
        matd_t * lookdir = matd_vec_normalize(lookeye);
        double dist =  matd_vec_dist(eye, lookat);
        dist  = fmin(state->zclip_far / 3.0, dist);
        dist  = fmax(state->zclip_near * 3.0, dist);

        matd_scale_inplace(lookdir, dist);

        matd_t * eye_fixed = matd_subtract(lookat, lookdir);

        memcpy(p->eye, eye_fixed->data, sizeof(double)*3);

        matd_destroy(eye);
        matd_destroy(lookat);
        matd_destroy(up);
        matd_destroy(lookeye);
        matd_destroy(lookdir);
        matd_destroy(eye_fixed);
    }

    // copy the result back into 'state'
    {
        memcpy(state->eye0, p->eye, 3*sizeof(double));
        memcpy(state->up0, p->up, 3*sizeof(double));
        memcpy(state->lookat0, p->lookat, 3*sizeof(double));
        state->perspectiveness0 = p->perspectiveness;
        state->mtime0 = mtime;
    }

    return p;
}
Exemple #11
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;
}
Exemple #12
0
// this loop tries to run at X fps, and issue render commands
static void * render_loop(void * foo)
{
    state_t * state = foo;
    if (verbose)printf("Starting render thread!\n");

    uint64_t render_count = 0;
    uint64_t last_mtime = vx_mtime();
    double avgDT = 1.0f/state->target_frame_rate;
    uint64_t avg_loop_us = 3000; // initial render time guess
    while (state->rendering) {
        int64_t sleeptime = (1000000 / state->target_frame_rate) - (int64_t) avg_loop_us;
        if (sleeptime > 0)
            usleep(sleeptime); // XXX fix to include render time

        // Diagnostic tracking
        uint64_t mtime_start = vx_mtime(); // XXX
        avgDT = avgDT*.9 + .1 * (mtime_start - last_mtime)/1000;
        last_mtime = mtime_start;
        render_count++;

        if (verbose) {
            if (render_count % 100 == 0)
                printf("Average render DT = %.3f FPS = %.3f avgloopus %"PRIu64" sleeptime = %"PRIi64"\n",
                       avgDT, 1.0/avgDT, avg_loop_us, sleeptime);
        }

        // prep the render data
        render_buffer_t rbuf;
        rbuf.state = state;
        rbuf.width = gtku_image_pane_get_width(state->imagePane);
        rbuf.height = gtku_image_pane_get_height(state->imagePane);
        if (rbuf.width == 0 && rbuf.height == 0)
            continue; // if the viewport is 0,0

        // smartly reuse, or reallocate the output pixel buffer when resizing occurs
        GdkPixbuf * pixbuf = state->pixbufs[state->cur_pb_idx];
        if (pixbuf == NULL || gdk_pixbuf_get_width(pixbuf) != rbuf.width || gdk_pixbuf_get_height(pixbuf) != rbuf.height) {
            if (pixbuf != NULL) {
                g_object_unref(pixbuf);
                free(state->pixdatas[state->cur_pb_idx]);
            }

            state->pixdatas[state->cur_pb_idx] = malloc(rbuf.width*rbuf.height*3); // can't stack allocate, can be too big (retina)
            pixbuf = gdk_pixbuf_new_from_data(state->pixdatas[state->cur_pb_idx], GDK_COLORSPACE_RGB, FALSE, 8,
                                              rbuf.width, rbuf.height, rbuf.width*3, NULL, NULL); // no destructor fn for pix data, handle manually
            state->pixbufs[state->cur_pb_idx] = pixbuf;
        }

        // second half of init:
        rbuf.out_buf = gdk_pixbuf_get_pixels(pixbuf);
        rbuf.format = GL_RGB;
        rbuf.rendered = 0;

        // 1 compute all the viewports
        render_info_t * rinfo = render_info_create();
        rinfo->viewport[0] = rinfo->viewport[1] = 0;
        rinfo->viewport[2] = rbuf.width;
        rinfo->viewport[3] = rbuf.height;

        {
            zhash_iterator_t itr;
            uint32_t layer_id = 0;
            layer_info_t * linfo = NULL;
            zhash_iterator_init(state->layer_info_map, &itr);
            while(zhash_iterator_next(&itr, &layer_id, &linfo)){
                zarray_add(rinfo->layers, &linfo);
            }
            zarray_sort(rinfo->layers, zvx_layer_info_compare);
        }

        zarray_t * fp = zarray_create(sizeof(matd_t*));

        matd_t *mm = matd_create(4,4); zarray_add(fp, &mm);
        matd_t *pm = matd_create(4,4); zarray_add(fp, &pm);

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

            int * viewport = vx_viewport_mgr_get_pos(linfo->vp_mgr, rinfo->viewport, mtime_start);
            vx_camera_pos_t *pos = default_cam_mgr_get_cam_pos(linfo->cam_mgr, viewport, mtime_start);

            // store viewport, pos
            zhash_put(rinfo->layer_positions, &linfo->layer_id, &viewport, NULL, NULL);
            zhash_put(rinfo->camera_positions, &linfo->layer_id, &pos, NULL, NULL);

            // feed the actual camera/projection matrix to the gl side
            vx_camera_pos_model_matrix(pos,mm->data);
            vx_camera_pos_projection_matrix(pos, pm->data);

            matd_t * pmmm = matd_multiply(pm,mm); zarray_add(fp, &pmmm);

            float pm16[16];
            vx_util_copy_floats(pmmm->data, pm16, 16);

            float eye3[16];
            vx_util_copy_floats(pos->eye, eye3, 3);

            vx_gl_renderer_set_layer_render_details(state->glrend, linfo->layer_id, viewport, pm16, eye3);
        }

        // 2 Render the data
        task_thread_schedule_blocking(gl_thread, render_task, &rbuf);

        render_info_t * old = state->last_render_info;
        state->last_render_info = rinfo;

        pthread_mutex_unlock(&state->mutex);


        // 3 if a render occurred, then swap gtk buffers
        if (rbuf.rendered) {

            // point to the correct buffer for the next render:
            state->cur_pb_idx = (state->cur_pb_idx +1 ) % 2;

            // flip y coordinate in place:
            vx_util_flipy(rbuf.width*3, rbuf.height, rbuf.out_buf);

            // swap the image's backing buffer
            g_object_ref(pixbuf); // XXX Since gtku always unrefs with each of these calls, increment accordingly
            gtku_image_pane_set_buffer(state->imagePane, pixbuf);
        }

        // 3.1 If a movie is in progress, also need to serialize the frame
        pthread_mutex_lock(&state->movie_mutex);
        if (state->movie_file != NULL) {

            int last_idx = (state->cur_pb_idx + 1) % 2;
            GdkPixbuf * pb = state->pixbufs[last_idx];

            movie_frame_t * movie_img = calloc(1, sizeof(movie_frame_t));
            movie_img->mtime = mtime_start;
            movie_img->width = gdk_pixbuf_get_width(pb);
            movie_img->height = gdk_pixbuf_get_height(pb);
            movie_img->stride = 3*movie_img->width;
            movie_img->buf = malloc(movie_img->stride*movie_img->height);
            memcpy(movie_img->buf, state->pixdatas[last_idx], movie_img->stride*movie_img->height);


            // Alloc in this thread, dealloc in movie thread
            zarray_add(state->movie_pending, & movie_img);

            pthread_cond_signal(&state->movie_cond);

        }
        pthread_mutex_unlock(&state->movie_mutex);


        // cleanup
        if (old)
            render_info_destroy(old);
        zarray_vmap(fp, matd_destroy);
        zarray_destroy(fp);


        uint64_t mtime_end = vx_mtime();
        avg_loop_us = (uint64_t)(.5*avg_loop_us + .5 * 1000 * (mtime_end - mtime_start));
    }
    if (verbose) printf("Render thread exiting\n");

    pthread_exit(NULL);

}
Exemple #13
0
vx_object_t * vxo_objmtl(const char * obj_filename)
{
    int  texture_flag = 0;

    FILE * fp_obj = fopen(obj_filename, "r");
    if (fp_obj == NULL)
        return NULL;

    #define LNSZ 1024
    char line_buffer[LNSZ];

    // Store 3D vertices by value
    zarray_t * vertices = zarray_create(sizeof(float)*3);
    zarray_t * textures = zarray_create(sizeof(float)*3);
    zarray_t * normals = zarray_create(sizeof(float)*3);

    wav_group_t * cur_group = NULL;
    zarray_t * group_list = zarray_create(sizeof(wav_group_t*));

    zhash_t * mtl_map = NULL; // created on reading mtllib entry
    //zhash_t * obj_map = zhash_create(sizeof(char*), sizeof(vx_object_t*), zhash_str_hash, zhash_str_equals);

    // Read in the entire file, save vertices, and indices for later processing.
    while (1) {
        int eof = fgets(line_buffer, LNSZ, fp_obj) == NULL;

        char * line = str_trim(line_buffer);

        // If possible, batch process the last group
        if (str_starts_with(line, "g ") || eof) {
            if (cur_group != NULL) {
                assert(cur_group->group_idx != NULL);

                zarray_add(group_list, &cur_group);
                cur_group = NULL;
            }
        }

        if (eof)
            break;


        if (str_starts_with(line, "#") || strlen(line) == 0 || !strcmp(line,"\r"))
            continue;

        if (str_starts_with(line, "g ")) {
            assert(mtl_map != NULL);

            char obj_name[LNSZ];
            sscanf(line, "g %s", obj_name);

            cur_group = calloc(1, sizeof(wav_group_t));
            cur_group->group_idx = zarray_create(sizeof(tri_idx_t));

        } else if (str_starts_with(line, "v ")) {
            float vertex[3];
            sscanf(line, "v %f %f %f", &vertex[0], &vertex[1], &vertex[2]);
            zarray_add(vertices, &vertex);
        } else if (str_starts_with(line, "vn ")) {
            float normal[3];
            sscanf(line, "vn %f %f %f", &normal[0], &normal[1], &normal[2]);
            zarray_add(normals, &normal);
        } else if (str_starts_with(line, "vt ")) {
            texture_flag = 1;
            float texture[3];
            sscanf(line, "vt %f %f %f", &texture[0], &texture[1], &texture[2]);
            zarray_add(textures, &texture);
        } else if (str_starts_with(line, "f ")) {
            tri_idx_t idxs;

            if (texture_flag) {
                sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d",
                       &idxs.vIdxs[0], &idxs.tIdxs[0], &idxs.nIdxs[0],
                       &idxs.vIdxs[1], &idxs.tIdxs[1], &idxs.nIdxs[1],
                       &idxs.vIdxs[2], &idxs.tIdxs[2], &idxs.nIdxs[2]);
            }
            else {
                sscanf(line, "f %d//%d %d//%d %d//%d",
                       &idxs.vIdxs[0], &idxs.nIdxs[0],
                       &idxs.vIdxs[1], &idxs.nIdxs[1],
                       &idxs.vIdxs[2], &idxs.nIdxs[2]);
            }

            zarray_add(cur_group->group_idx, &idxs);

        } else if (str_starts_with(line, "usemtl ")) {
            char *mname = calloc(1, sizeof(char)*1024);
            sscanf(line, "usemtl %s", mname);
            zhash_get(mtl_map, &mname, &cur_group->material);
            free(mname);
        } else if (str_starts_with(line, "s ")) {
            // No idea what to do with smoothing instructions
        } else if (str_starts_with(line, "mtllib ")) {
            char * cur_path = strdup(obj_filename);
            const char * dir_name = dirname(cur_path);

            char mtl_basename[LNSZ];
            sscanf(line, "mtllib %s", mtl_basename);

            char mtl_filename[LNSZ];
            sprintf(mtl_filename,"%s/%s", dir_name, mtl_basename);

            mtl_map = load_materials(mtl_filename);
            if (mtl_map == NULL) {
                zarray_destroy(vertices);
                zarray_destroy(normals);
                return NULL; // XXX cleanup!
            }
            free(cur_path);
        } else {
            printf("Did not parse: %s\n", line);

            for (int i = 0; i < strlen(line); i++) {
                printf("0x%x ", (int)line[i]);
            }
            printf("\n");
        }
    }

    if (1) // useful to enable when compensating for model scale
        print_bounds(vertices);

    // Process the model sections in two passes -- first add all the
    // objects which are not transparent. Then render transparent
    // objects after

    vx_object_t * vchain = vxo_chain_create();

    zarray_t * sorted_groups = zarray_create(sizeof(wav_group_t*));
    for (int i = 0, sz = zarray_size(group_list); i < sz; i++) {
        wav_group_t * group = NULL;
        zarray_get(group_list, i, &group);

        // add to front if solid
        if (group->material.d == 1.0f) {
            zarray_insert(sorted_groups, 0, &group);
        } else { // add to back if transparent
            zarray_add(sorted_groups, &group);
        }
    }

    int total_triangles = 0;
    for (int i = 0, sz = zarray_size(sorted_groups); i < sz; i++) {
        wav_group_t * group = NULL;
        zarray_get(sorted_groups, i, &group);

        int ntri =  zarray_size(group->group_idx);

        vx_resc_t * vert_resc = vx_resc_createf(ntri*9);
        vx_resc_t * norm_resc = vx_resc_createf(ntri*9);

        for (int j = 0; j < ntri; j++) {
            tri_idx_t idxs;
            zarray_get(group->group_idx, j, &idxs);

            for (int  i = 0; i < 3; i++) {
                zarray_get(vertices, idxs.vIdxs[i]-1, &((float*)vert_resc->res)[9*j + i*3]);
                zarray_get(normals,  idxs.nIdxs[i]-1, &((float*)norm_resc->res)[9*j + i*3]);
            }
        }

        vx_style_t * sty = vxo_mesh_style_fancy(group->material.Ka, group->material.Kd, group->material.Ks, group->material.d, group->material.Ns, group->material.illum);
        vxo_chain_add(vchain, vxo_mesh(vert_resc, ntri*3, norm_resc, GL_TRIANGLES, sty));

        total_triangles += ntri;
    }

    //Cleanup:
    // 1. Materials, names are by reference, but materials are by value
    zhash_vmap_keys(mtl_map, free);
    zhash_destroy(mtl_map);

    // 2. Geometry
    zarray_destroy(vertices); // stored by value
    zarray_destroy(normals); // stored by value

    // 2b wav_group_t are stored by reference

    zarray_vmap(group_list, wav_group_destroy);
    zarray_destroy(group_list);
    zarray_destroy(sorted_groups); // duplicate list, so don't need to free

    fclose(fp_obj);

    return vchain;
}
Exemple #14
0
loc_t* fit_lines(image_u32_t* im, node_t* n, vx_buffer_t* buf, metrics_t met, loc_t* out)
{
    // usleep(2000000);
    srand(time(NULL));
    // isolate valid entries 
    zarray_t* loc_arr = zarray_create(sizeof(loc_t*));
   
    for(int i = 0; i < im->height; i++) {
        if(n->sides[i].leftmost.x == im->width) continue;        // not apart of blob


        loc_t* loc = malloc(sizeof(loc_t));
        loc->x = n->sides[i].leftmost.x;
        loc->y = n->sides[i].leftmost.y;
        loc->valid = 0;
        zarray_add(loc_arr, &loc);
    }
    for(int i = 0; i < im->height; i++) {
        if(n->sides[i].rightmost.x == -1) continue;

        loc_t* loc = malloc(sizeof(loc_t));
        loc->x = n->sides[i].rightmost.x;
        loc->y = n->sides[i].rightmost.y;
        loc->valid = 0;
        zarray_add(loc_arr, &loc);
    }

    // printf("\n\nall\n");
    // for(int i = 0; i < zarray_size(loc_arr); i++)
    // {
    //     loc_t* p1;
    //     zarray_get(loc_arr, i, &p1);
    //     printf("(%d, %d)\n", p1->x, p1->y);
    // }
    // printf("\n\n");
    int iterations = 0;
    int best_score = 0;
    int lines_found = 0;
    loc_t line_match[8];
    int max_iterations = 500;
    while(lines_found < 2  && zarray_size(loc_arr) > met.num_outliers)      // still a lot of points left 
    {  
        if(iterations > max_iterations) break;
        // reset image and array
        // vx_object_t *vim = vxo_image_from_u32(im, 0, 0);
        // vx_buffer_add_back(buf, vxo_pix_coords(VX_ORIGIN_BOTTOM_LEFT, vim));
        add_arr_of_locs_to_buffer(loc_arr, buf, 1.0, vx_black, met);

        int num_outliers = met.num_outliers/met.consensus_accuracy;

        while(best_score < ((zarray_size(loc_arr) - num_outliers)/(4 - lines_found)))
        {
            reset_locs(loc_arr);
            // pick random sample (2 points)
            loc_t* p1;
            loc_t* p2;
            zarray_get(loc_arr, (rand()%zarray_size(loc_arr)), &p1);
            p2 = p1;
            while(p1 == p2)
                zarray_get(loc_arr, (rand()%zarray_size(loc_arr)), &p2);    // don't get same point

            // find consensus score of line from other points 
            // if inside consensus range add 1
            int tmp_score = 0;
            for(int j = 0; j < zarray_size(loc_arr); j++) {
                loc_t* tmp;
                zarray_get(loc_arr, j, &tmp);
                if(fabs(dist_from_point_to_line(p1, p2, tmp)) < (double)met.consensus_accuracy) 
                {

                    tmp->valid = 1;
                    // printf("dist: (%d, %d, %d)  %lf\n", tmp->x, tmp->y, tmp->valid,
                    //         fabs(dist_from_point_to_line(p1, p2, tmp)));
                    tmp_score++;
                }
            }
            // keep best line so far 
            if(tmp_score > best_score) {
                if(lines_found != 0) {      // if 2nd line intersects, throw it out and find another 
                    loc_t intersect = get_line_intersection(line_match[0], line_match[1], *p1, *p2);
                        if(in_range(im, intersect.x, intersect.y)) continue;
                }
                best_score = tmp_score;
                // printf("      score:%d,  %d,  %d  %lf\n", best_score, ((zarray_size(loc_arr)-1)/(4-lines_found)), 
                //                                     zarray_size(loc_arr), 10/met.std_dev_from_square);
                line_match[lines_found*2] = *p1;
                line_match[lines_found*2+1] = *p2;
            }
            iterations++;
            if(iterations > max_iterations) break;
        }
        // loc_t ext_lines[2];
        // extend_lines_to_edge_of_image(im, line_match[lines_found*2], line_match[lines_found*2+1], ext_lines);
        // add_line_to_buffer(im, buf, 2.0, ext_lines[0], ext_lines[1], vx_yellow);
        // delete all points associated with the found line
        zarray_t* endpoints_arr = zarray_create(sizeof(loc_t*));
        for(int i = 0; i < zarray_size(loc_arr); i++) {
            loc_t* tmp;
            zarray_get(loc_arr, i, &tmp);
            // printf("removed: (%d, %d, %d) \n", tmp->x, tmp->y, tmp->valid);
            if(tmp->valid) 
            {
                // add_circle_to_buffer(buf,  1.0, *tmp, vx_red);
                zarray_add(endpoints_arr, &tmp);
                zarray_remove_index(loc_arr, i, 0);
                i--;
            }
        }
        // find endpoints of line 
        loc_t ext_lines[2];
        extend_lines_to_edge_of_image(im, line_match[lines_found*2], line_match[lines_found*2+1], ext_lines);
        line_t endpoints = find_line_endpoints(endpoints_arr, &ext_lines[0], &ext_lines[1]);
        add_circle_to_buffer(buf,  2.0, endpoints.start, vx_red);
        add_circle_to_buffer(buf,  2.0, endpoints.end, vx_red);
        line_match[lines_found*2] = endpoints.start;
        line_match[lines_found*2+1] = endpoints.end;

        lines_found++;
        best_score = 0;
        // vx_buffer_swap(buf);
        // usleep(500000);
    }

    loc_t* ret = calloc(lines_found*2, sizeof(loc_t));
    for(int i = 0; i < lines_found; i++) {
        ret[i*2] = line_match[i*2];
        ret[i*2+1] = line_match[i*2+1]; 
        loc_t ext_lines[2];
        extend_lines_to_edge_of_image(im, line_match[i*2], line_match[i*2+1], ext_lines);
        add_line_to_buffer(im, buf, 2.0, ext_lines[0], ext_lines[1], vx_blue);
    }

    zarray_vmap(loc_arr, free);
    zarray_destroy(loc_arr);
    return(ret);

    // int corners_found = 0;
    // loc_t corners[4];
    // find_corners_from_lines(im,line_match, 4, &corners_found, corners);
    // for(int i = 0; i < corners_found; i++) {
    //     printf("(%d, %d)\n", corners[i].x, corners[i].y);
    //     add_circle_to_buffer(buf, 3.0, corners[i], vx_blue);
    // }

    // printf("(%d, %d) (%d, %d)   %lf\n", line_match[0].x, line_match[0].y, 
    //                                     line_match[1].x, line_match[1].y, 
    //                                     (double)best_score/N);

}
Exemple #15
0
// Call this only from the serialization thread
//
static void delayed_swap(vx_buffer_t * buffer)
{
    if (!buffer->front_objs)
        return; // buffer has not yet finished initialization
    if (verbose) printf("DBG: swap %s\n", buffer->name);

    pthread_mutex_lock(&buffer->mutex);
    {
        // clear existing front
        buffer->front_codes->pos = 0; // reset

        // *+*+ corresponding decrement (if keeping up)
        zarray_vmap(buffer->front_objs, vx_object_dec_destroy);
        zarray_clear(buffer->front_objs);


        // swap out the pending objects without tying up this mutex for too long
        zarray_t * tmp = buffer->front_objs;
        buffer->front_objs = buffer->pending_objs;
        buffer->pending_objs = tmp; // empty
    }
    pthread_mutex_unlock(&buffer->mutex);

    vx_world_t * world = buffer->world;
    zhash_t * old_resources = buffer->front_resc;

    // Serialize each object into resources and opcodes
    vx_code_output_stream_t * codes = buffer->front_codes;

    codes->write_uint32(codes, OP_BUFFER_CODES);
    codes->write_uint32(codes, world->worldID);
    codes->write_str(codes, buffer->name);
    codes->write_uint32(codes, buffer->draw_order); // XXX We should move this op code elsewhere

    zhash_t * resources = zhash_create(sizeof(uint64_t),sizeof(vx_resc_t*), zhash_uint64_hash, zhash_uint64_equals);

    for (int i = 0; i < zarray_size(buffer->front_objs); i++) {
        vx_object_t * obj = NULL;
        zarray_get(buffer->front_objs, i, &obj);
        obj->append(obj, resources, codes);
    }

    // *&&* we will hold on to these until next swap() call
    zhash_vmap_values(resources, vx_resc_inc_ref);

    zhash_t * all_resources = zhash_copy(resources);
    addAll(all_resources, old_resources);

    // Claim use of the union of the last frame, and the current frame
    // this avoids a race condition where another buffer (maybe in another world)
    // could force deallocation of some resources before the new render codes arrive
    if (verbose) printf("DBG: claim union via codes\n");
    if (verbose > 1)  {
        printf("  claimed %d IDS ", zhash_size(all_resources));
        zhash_vmap_values(all_resources, _print_id);
        printf("\n");
    }
    send_buffer_resource_codes(buffer, all_resources);

    if (verbose) printf("DBG: Send actual resources\n");
    if (verbose > 1)  {
        printf("  send %d IDS ", zhash_size(all_resources));
        zhash_vmap_values(all_resources, _print_id);
        printf("\n");
    }
    notify_listeners_send_resources(world, all_resources);

    if (verbose) printf("DBG: send render codes\n");
    notify_listeners_codes(world, codes);

    // Claim the actual set of resources which are in use now, which may result in some
    // resources being deleted from the gl context
    if (verbose) printf("DBG: reduce claim to actual in use\n");
    if (verbose > 1)  {
        printf("  actual %d IDS ", zhash_size(resources));
        zhash_vmap_values(resources, _print_id);
        printf("\n\n");
    }
    send_buffer_resource_codes(buffer, resources);



    buffer->front_resc = resources; // set of current resources

    zhash_destroy(all_resources);

    // *&&* corresponding decrement of resources
    zhash_vmap_values(old_resources, vx_resc_dec_destroy);
    zhash_destroy(old_resources);

}