void buffer_enabled(vx_gtk_buffer_manager_t * man, vx_code_input_stream_t * cins)
{
    int layer_id = cins->read_uint32(cins);
    const char * name = cins->read_str(cins);
    uint8_t enabled = cins->read_uint8(cins);

    int update = 0;
    pthread_mutex_lock(&man->mutex);
    {
        /* char * alloc_name = strdup(name); */
        layer_info_t * linfo = NULL;
        zhash_get(man->layers, &layer_id, &linfo);
        if (linfo == NULL) {
            pthread_mutex_unlock(&man->mutex);
            return; // XXXX assert?
        }

        buffer_info_t * buffer = NULL;
        if (zhash_get(linfo->buffers, &name, &buffer)) {
            buffer->enabled = enabled;
            update = 1;
        }
    }
    pthread_mutex_unlock(&man->mutex);

    if (update == 1)
        queue_update_view(man);


}
Beispiel #2
0
static void process_layer(state_t * state, vx_code_input_stream_t * cins)
{
    // update (or create) the layer_info_t

    int layer_id = cins->read_uint32(cins);
    int world_id = cins->read_uint32(cins);
    int draw_order = cins->read_uint32(cins);
    int bg_color = cins->read_uint32(cins);

    layer_info_t * linfo = NULL;
    zhash_get(state->layer_info_map, &layer_id, &linfo);


    if (linfo == NULL) {

        linfo = calloc(1,sizeof(layer_info_t));

        linfo->cam_mgr = default_cam_mgr_create();
        linfo->event_handler = default_event_handler_create(linfo->cam_mgr, UI_ANIMATE_MS);
        linfo->vp_mgr = vx_viewport_mgr_create();

        zhash_put(state->layer_info_map, &layer_id, &linfo, NULL, NULL);
    }

    linfo->layer_id = layer_id;
    linfo->draw_order = draw_order;

    bg_color+=world_id; // XXX unused variable
}
Beispiel #3
0
static void zhash_set_test()
{
  size_t size, ii;
  char **keys, **vals;
  struct ZHashTable *hash_table;

  size = 100;
  hash_table = zcreate_hash_table();
  keys = malloc(size * sizeof(char *));
  vals = malloc(size * sizeof(char *));

  for (ii = 0; ii < size; ii++) {
    keys[ii] = random_string();
    vals[ii] = random_string();
    zhash_set(hash_table, keys[ii], (void *) vals[ii]);
  }

  assert(hash_table->size_index == 2);
  assert(hash_table->entry_count == size);

  for (ii = 0; ii < size; ii++) {
    assert(strcmp(zhash_get(hash_table, keys[ii]), vals[ii]) == 0);
  }

  for (ii = 0; ii < size; ii++) {
    free(keys[ii]);
    free(vals[ii]);
  }

  free(keys);
  free(vals);
  zfree_hash_table(hash_table);
}
Beispiel #4
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
}
Beispiel #5
0
vx_buffer_t * vx_world_get_buffer(vx_world_t * world, const char * name)
{
    vx_buffer_t * buffer = NULL;

    pthread_mutex_lock(&world->buffer_mutex);

    zhash_get(world->buffer_map, &name, &buffer);
    if (buffer == NULL) {
        buffer = calloc(1, sizeof(vx_buffer_t));

        buffer->name = strdup(name);
        buffer->world = world;
        buffer->draw_order = 0;

        buffer->back_objs = zarray_create(sizeof(vx_object_t*));
        buffer->pending_objs = zarray_create(sizeof(vx_object_t*));
        buffer->front_objs = zarray_create(sizeof(vx_object_t*));

        buffer->front_resc = zhash_create(sizeof(uint64_t), sizeof(vx_resc_t*), zhash_uint64_hash, zhash_uint64_equals);
        buffer->front_codes = vx_code_output_stream_create(128);

        pthread_mutex_init(&buffer->mutex, NULL);

        vx_buffer_t * oldBuffer= NULL;
        zhash_put(buffer->world->buffer_map, &buffer->name, &buffer, NULL, &oldBuffer);
        assert(oldBuffer == NULL);
    }

    pthread_mutex_unlock(&world->buffer_mutex);

    return buffer;
}
void process_buffer(vx_gtk_buffer_manager_t * man, vx_code_input_stream_t * cins)
{
    int world_id = cins->read_uint32(cins);
    const char * name = cins->read_str(cins);
    int draw_order = cins->read_uint32(cins);

    // find a matching layer:
    int update = 0;
    pthread_mutex_lock(&man->mutex);
    {
        layer_info_t * linfo = NULL;
        int layer_id = 0;
        zhash_iterator_t itr;
        zhash_iterator_init(man->layers, &itr);
        while(zhash_iterator_next(&itr, &layer_id, &linfo)) {
            if (linfo->world_id == world_id) {
                break;
            }
        }

        if (linfo == NULL) { // XXX Assert?
            pthread_mutex_unlock(&man->mutex);
            return;
        }

        // Now ensure there's a buffer_info_t in this layer.
        buffer_info_t * buffer = NULL;
        int success = zhash_get(linfo->buffers, &name, &buffer);

        // buffer doesn't exist yet?
        if (!success) {
            buffer = calloc(1, sizeof(buffer_info_t));
            buffer->layer_id = linfo->layer_id;
            buffer->name = strdup(name);
            buffer->enabled = 1;
            buffer->draw_order = draw_order;
            buffer->man = man;

            zhash_put(linfo->buffers, &buffer->name, &buffer, NULL, NULL);

            update = 1;
        }

        // draw order changed?
        if (success && draw_order != buffer->draw_order) {
            assert(buffer != NULL);
            buffer->draw_order = draw_order;

            update = 1;
        }
    }
    pthread_mutex_unlock(&man->mutex);

    if (update == 1)
        queue_update_view(man);
}
const char *
getopt_get_string (getopt_t *gopt, const char *lname)
{
    getopt_option_t *goo = NULL;
    zhash_get (gopt->lopts, &lname, &goo);
    // could return null, but this would be the only
    // method that doesn't assert on a missing key
    assert (goo != NULL);
    return goo->svalue;
}
int
getopt_was_specified (getopt_t *getopt, const char *lname)
{
    getopt_option_t *goo = NULL;
    zhash_get (getopt->lopts, &lname, &goo);
    if (goo == NULL)
        return 0;

    return goo->was_specified;
}
Beispiel #9
0
// gcc -Wall -Wextra hello.c ../src/zhash.c
// prints "hello world" to stdout
int main ()
{
  struct ZHashTable *hash_table;
  
  hash_table = zcreate_hash_table();
  
  zhash_set(hash_table, "hello", (void *) "world");

  if (zhash_exists(hash_table, "hello")) {
    printf("hello %s\n", (char *) zhash_get(hash_table, "hello"));
  }
  
  if (zhash_exists(hash_table, "goodbye")) {
    printf("goodbye %s\n", (char *) zhash_get(hash_table, "goodbye"));
  }

  zfree_hash_table(hash_table);

  return 0;
}
Beispiel #10
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;
}
Beispiel #11
0
static void zhash_exists_test()
{
  struct ZHashTable *hash_table;

  hash_table = zcreate_hash_table();

  zhash_set(hash_table, "hello", (void *) "world");
  zhash_set(hash_table, "nothing", NULL);

  assert(zhash_exists(hash_table, "hello") == true);
  assert(zhash_exists(hash_table, "nothing") == true);
  assert(zhash_get(hash_table, "nothing") == NULL);
  assert(zhash_exists(hash_table, "nope") == false);

  zfree_hash_table(hash_table);
}
Beispiel #12
0
static void process_viewport_rel(state_t * state, vx_code_input_stream_t * cins)
{
    int layer_id = cins->read_uint32(cins);

    float rel[] = {cins->read_float(cins),
                   cins->read_float(cins),
                   cins->read_float(cins),
                   cins->read_float(cins)};
    int animate_ms = cins->read_uint32(cins);
    uint64_t mtime_goal = vx_mtime() + animate_ms;

    layer_info_t * linfo = NULL;
    zhash_get(state->layer_info_map, &layer_id, &linfo);
    if (linfo == NULL)
        return;

    vx_viewport_mgr_set_rel(linfo->vp_mgr,rel, mtime_goal);
}
void process_layer(vx_gtk_buffer_manager_t * man, vx_code_input_stream_t * cins)
{
    int layer_id = cins->read_uint32(cins);
    int world_id = cins->read_uint32(cins);
    int draw_order = cins->read_uint32(cins);
    /* int bg_color = cins->read_uint32(cins); */

    int update = 0;
    pthread_mutex_lock(&man->mutex);
    {
        layer_info_t * linfo = NULL;
        int success = zhash_get(man->layers, &layer_id, &linfo);

        if (!success) {
            linfo = calloc(1,sizeof(layer_info_t));
            linfo->layer_id = layer_id;
            linfo->world_id = world_id;
            linfo->buffers = zhash_create(sizeof(char*), sizeof(buffer_info_t*), zhash_str_hash, zhash_str_equals);

            zhash_put(man->layers, &layer_id, &linfo, NULL, NULL);
            update = 1;
        }

        if (success && draw_order != linfo->draw_order) {
            assert(linfo != NULL);
            linfo->draw_order = draw_order;

            update = 1;
        }
        assert(linfo->world_id == world_id);
    }
    pthread_mutex_unlock(&man->mutex);

    if (update == 1)
        queue_update_view(man);

}
Beispiel #14
0
static void process_viewport_abs(state_t * state, vx_code_input_stream_t * cins)
{

    int layer_id = cins->read_uint32(cins);
    int align_code = cins->read_uint32(cins);

    int offx = cins->read_uint32(cins);
    int offy = cins->read_uint32(cins);

    int width = cins->read_uint32(cins);
    int height = cins->read_uint32(cins);

    int animate_ms = cins->read_uint32(cins);
    uint64_t mtime_goal = vx_mtime() + animate_ms;

    layer_info_t * linfo = NULL;
    zhash_get(state->layer_info_map, &layer_id, &linfo);
    if (linfo == NULL)
        return;

    vx_viewport_mgr_set_abs(linfo->vp_mgr, align_code,
                            offx, offy, width, height, mtime_goal);

}
// 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;
}
Beispiel #16
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;
}
Beispiel #17
0
void hsv_find_balls_blob_detector(image_u32_t* im, frame_t frame, metrics_t met, zarray_t* blobs_out)
{
    assert(frame.xy0.x < frame.xy1.x && frame.xy0.y < frame.xy1.y);
    assert(frame.xy0.x >= 0 && frame.xy0.y >= 0 && frame.xy1.x < im->width && frame.xy1.y < im->height);
    assert(frame.ex0.x < frame.ex1.x && frame.ex0.y < frame.ex1.y);
    assert(frame.ex0.x >= 0 && frame.ex0.y >= 0 && frame.ex1.x < im->width && frame.ex1.y < im->height);

    // Int to node
    zhash_t* node_map = zhash_create(sizeof(uint32_t), sizeof(node_t*),
            zhash_uint32_hash, zhash_uint32_equals);

    for(int i = frame.xy0.y; i < frame.xy1.y; i++) {
        for(int j = frame.xy0.x; j < frame.xy1.x; j++) {
            if((i < frame.ex0.y || i > frame.ex1.y) || (j < frame.ex0.x || j > frame.ex1.x)) {

                uint32_t idx_im = i * im->stride + j; // Indframe.ex relative to image

                // Pixel color data
                uint32_t abgr = im->buf[idx_im];
                hsv_t hsv = {0,0,0};
                rgb_to_hsv(abgr, &hsv);
                hsv_t error = {fabs(hsv.hue - met.hsv.hue), 
                                fabs(hsv.sat - met.hsv.sat), 
                                fabs(hsv.val - met.hsv.val)};

                // 'Acceptable'
                 if((error.hue < met.error.hue) && 
                    (error.sat < met.error.sat) && 
                    (error.val < met.error.val)) 
                 {
                    // Create new node, set itself up as a parent
                    node_t* n = calloc(1, sizeof(node_t));
                    n->id = idx_im;
                    n->parent_id = idx_im;
                    n->parent_node = n;
                    n->num_children = 0;

                    node_t* tmp_node;
                    uint32_t tmp_idx;

                    // Add node to node map
                    if(zhash_put(node_map, &idx_im, &n, &tmp_idx, &tmp_node)==1) 
                    {
                        assert(0);
                    }

                    //Check if apart of another blob, or starting a new blob 
                    // if apart of another, point to the parent, if a new blob, point to self 
                    //Check neighbours
                    if(!met.lines) {    // only check this if don't want lines for tape detection
                        if(j > frame.xy0.x) {
                            tmp_idx = idx_im - 1; // is Left neighbour similar color 
                            if(zhash_get(node_map, &tmp_idx, &tmp_node) == 1) {
                                node_t* neighbour = tmp_node;
                                connect(n, neighbour);                    
                            }
                        }
                    }
                    if(i > frame.xy0.y) { 
                        tmp_idx = idx_im - im->stride; // is Bottom neighbor similar color
                        if(tmp_idx > 0 && zhash_get(node_map, &tmp_idx, &tmp_node) == 1) {
                            node_t* neighbour = tmp_node;
                            connect(neighbour,n);                    
                        }
                    }
                }
            }
        }
    }


    //count number of children for each parent, go through node_map
    // if a node is not a parent, add 1 to it's parent->num_children and delete from hash
    // if is a parent do nothing
    zarray_t* vals = zhash_values(node_map);
    for(int i = 0; i < zarray_size(vals); i++) {
        node_t* node;
        zarray_get(vals, i, &node);
        resolve_r(node);

        if(node->parent_id != node->id) {
            node->parent_node->num_children++;
            // key should exist, if it doesn't find out why
            assert(zhash_remove(node_map, &node->id, NULL, NULL));
        }
    }

    // search parent only hash and add to blobs out conditionally
    vals = zhash_values(node_map);
    for(int i = 0; i < zarray_size(vals); i++) {
        node_t* node;
        zarray_get(vals, i, &node);
        if(node->num_children > met.min_size) {
            loc_t pos;
            pos.x = node->parent_id%im->stride;
            pos.y = node->parent_id/im->stride;
            zarray_add(blobs_out, &pos);
            // printf("parent %d\n", node->id);
        }
    }
    zarray_destroy(vals);
    zhash_vmap_values(node_map, free);
    zhash_destroy(node_map);
}
zarray_t *apriltag_quad_thresh(apriltag_detector_t *td, image_u8_t *im)
{
    ////////////////////////////////////////////////////////
    // step 1. threshold the image, creating the edge image.

    int w = im->width, h = im->height, s = im->stride;

    image_u8_t *threshim = threshold(td, im);
    assert(threshim->stride == s);

    image_u8_t *edgeim = image_u8_create(w, h);

    if (1) {
        image_u8_t *sumim = image_u8_create(w, h);

        // apply a horizontal sum kernel of width 3
        for (int y = 0; y < h; y++) {
            for (int x = 1; x+1 < w; x++) {

                sumim->buf[y*s + x] =
                    threshim->buf[y*s + x - 1] +
                    threshim->buf[y*s + x + 0] +
                    threshim->buf[y*s + x + 1];
            }
        }
        timeprofile_stamp(td->tp, "sumim");

        // deglitch
        if (td->qtp.deglitch) {
            for (int y = 1; y+1 < h; y++) {
                for (int x = 1; x+1 < w; x++) {
                    // edge: black pixel next to white pixel
                    if (threshim->buf[y*s + x] == 0 &&
                        sumim->buf[y*s + x - s] + sumim->buf[y*s + x] + sumim->buf[y*s + x + s] == 8) {
                        threshim->buf[y*s + x] = 1;
                        sumim->buf[y*s + x - 1]++;
                        sumim->buf[y*s + x + 0]++;
                        sumim->buf[y*s + x + 1]++;
                    }

                    if (threshim->buf[y*s + x] == 1 &&
                        sumim->buf[y*s + x - s] + sumim->buf[y*s + x] + sumim->buf[y*s + x + s] == 1) {
                        threshim->buf[y*s + x] = 0;
                        sumim->buf[y*s + x - 1]--;
                        sumim->buf[y*s + x + 0]--;
                        sumim->buf[y*s + x + 1]--;
                   }
                }
            }

            timeprofile_stamp(td->tp, "deglitch");
        }

        // apply a vertical sum kernel of width 3; check if any
        // over-threshold pixels are adjacent to an under-threshold
        // pixel.
        //
        // There are two types of edges: white pixels neighboring a
        // black pixel, and black pixels neighboring a white pixel. We
        // label these separately.  (Values 0xc0 and 0x3f are picked
        // such that they add to 255 (see below) and so that they can be
        // viewed as pixel intensities for visualization purposes.)
        //
        // symmetry of detection. We don't want to use JUST "black
        // near white" (or JUST "white near black"), because that
        // biases the detection towards one side of the edge. This
        // measurably reduces detection performance.
        //
        // On large tags, we could treat "neighbor" pixels the same
        // way. But on very small tags, there may be other edges very
        // near the tag edge. Since each of these edges is effectively
        // two pixels thick (the white pixel near the black pixel, and
        // the black pixel near the white pixel), it becomes likely
        // that these two nearby edges will actually touch.
        //
        // A partial solution to this problem is to define edges to be
        // adjacent white-near-black and black-near-white pixels.
        //

        for (int y = 1; y+1 < h; y++) {
            for (int x = 1; x+1 < w; x++) {
                if (threshim->buf[y*s + x] == 0) {
                    // edge: black pixel next to white pixel
                    if (sumim->buf[y*s + x - s] + sumim->buf[y*s + x] + sumim->buf[y*s + x + s] > 0)
                        edgeim->buf[y*s + x] = 0xc0;
                } else {
                    // edge: white pixel next to black pixel when both
                    // edge types are on, we get less bias towards one
                    // side of the edge.
                    if (sumim->buf[y*s + x - s] + sumim->buf[y*s + x] + sumim->buf[y*s + x + s] < 9)
                        edgeim->buf[y*s + x] = 0x3f;
                }
            }
        }

        if (td->debug) {
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    threshim->buf[y*s + x] *= 255;
                }
            }

            image_u8_write_pnm(threshim, "debug_threshold.pnm");
            image_u8_write_pnm(edgeim, "debug_edge.pnm");
//            image_u8_destroy(edgeim2);
        }

        image_u8_destroy(threshim);
        image_u8_destroy(sumim);
    }

    timeprofile_stamp(td->tp, "edges");

    ////////////////////////////////////////////////////////
    // step 2. find connected components.

    unionfind_t *uf = unionfind_create(w * h);

    for (int y = 1; y < h - 1; y++) {
        for (int x = 1; x < w -1; x++) {
            uint8_t v = edgeim->buf[y*s + x];
            if (v==0)
                continue;

            // (dx,dy) pairs for 8 connectivity:
            //          (REFERENCE) (1, 0)
            // (-1, 1)    (0, 1)    (1, 1)
            //
            // i.e., the minimum value of dx should be:
            //   y=0:   1
            //   y=1:  -1
            for (int dy = 0; dy <= 1; dy++) {
                for (int dx = 1-2*dy; dx <= 1; dx++) {
                    if (edgeim->buf[(y+dy)*s + (x+dx)] == v) {
                        unionfind_connect(uf, y*w + x, (y+dy)*w + x + dx);
                    }
                }
            }
        }
    }

    timeprofile_stamp(td->tp, "unionfind");

    zhash_t *clustermap = zhash_create(sizeof(uint64_t), sizeof(zarray_t*),
                                       zhash_uint64_hash, zhash_uint64_equals);

    for (int y = 1; y < h-1; y++) {
        for (int x = 1; x < w-1; x++) {

            uint8_t v0 = edgeim->buf[y*s + x];
            if (v0 == 0)
                continue;

            uint64_t rep0 = unionfind_get_representative(uf, y*w + x);

            // 8 connectivity. (4 neighbors to check).
//            for (int dy = 0; dy <= 1; dy++) {
//                for (int dx = 1-2*dy; dx <= 1; dx++) {

            // 4 connectivity. (2 neighbors to check)
            for (int n = 1; n <= 2; n++) {
                int dy = n & 1;
                int dx = (n & 2) >> 1;

                uint8_t v1 = edgeim->buf[(y+dy)*s + x + dx];
                if (v0 + v1 != 255)
                    continue;
                uint64_t rep1 = unionfind_get_representative(uf, (y+dy)*w + x+dx);

                uint64_t clusterid;
                if (rep0 < rep1)
                    clusterid = (rep1 << 32) + rep0;
                else
                    clusterid = (rep0 << 32) + rep1;

                zarray_t *cluster = NULL;
                if (!zhash_get(clustermap, &clusterid, &cluster)) {
                    cluster = zarray_create(sizeof(struct pt));
                    zhash_put(clustermap, &clusterid, &cluster, NULL, NULL);
                }

                // NB: We will add some points multiple times to a
                // given cluster.  I don't know an efficient way to
                // avoid that here; we remove them later on when we
                // sort points by pt_compare_theta.
                if (1) {
                    struct pt p = { .x = x, .y = y};
                    zarray_add(cluster, &p);
                }
                if (1) {
                    struct pt p = { .x = x+dx, .y = y+dy};
                    zarray_add(cluster, &p);
                }
            }
        }
    }

    // make segmentation image.
    if (td->debug) {
        image_u8_t *d = image_u8_create(w, h);
        assert(d->stride == s);

        uint8_t *colors = (uint8_t*) calloc(w*h, 1);

        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                uint32_t v = unionfind_get_representative(uf, y*w+x);
                uint32_t sz = unionfind_get_set_size(uf, y*w+x);
                if (sz < td->qtp.min_cluster_pixels)
                    continue;

                uint8_t color = colors[v];

                if (color == 0) {
                    const int bias = 20;
                    color = bias + (random() % (255-bias));
                    colors[v] = color;
                }

                float mix = 0.7;
                mix = 1.0;
                d->buf[y*d->stride + x] = mix*color + (1-mix)*im->buf[y*im->stride + x];
            }
        }

        free(colors);

        image_u8_write_pnm(d, "debug_segmentation.pnm");
        image_u8_destroy(d);
    }

    timeprofile_stamp(td->tp, "make clusters");


    ////////////////////////////////////////////////////////
    // step 3. process each connected component.

    zarray_t *clusters = zhash_values(clustermap);
    zhash_destroy(clustermap);

    zarray_t *quads = zarray_create(sizeof(struct quad));

    int sz = zarray_size(clusters);
    int chunksize = 1 + sz / (APRILTAG_TASKS_PER_THREAD_TARGET * td->nthreads);
    struct quad_task tasks[sz / chunksize + 1];

    int ntasks = 0;
    for (int i = 0; i < sz; i += chunksize) {
        tasks[ntasks].td = td;
        tasks[ntasks].cidx0 = i;
        tasks[ntasks].cidx1 = imin(sz, i + chunksize);
        tasks[ntasks].h = h;
        tasks[ntasks].w = w;
        tasks[ntasks].quads = quads;
        tasks[ntasks].clusters = clusters;
        tasks[ntasks].im = im;

        workerpool_add_task(td->wp, do_quad_task, &tasks[ntasks]);
        ntasks++;
    }

    workerpool_run(td->wp);

    timeprofile_stamp(td->tp, "fit quads to clusters");

    if (td->debug) {
        FILE *f = fopen("debug_lines.ps", "w");
        fprintf(f, "%%!PS\n\n");

        image_u8_t *im2 = image_u8_copy(im);
        image_u8_darken(im2);
        image_u8_darken(im2);

        // assume letter, which is 612x792 points.
        double scale = fmin(612.0/im->width, 792.0/im2->height);
        fprintf(f, "%.15f %.15f scale\n", scale, scale);
        fprintf(f, "0 %d translate\n", im2->height);
        fprintf(f, "1 -1 scale\n");

        postscript_image(f, im);

        for (int i = 0; i < zarray_size(quads); i++) {
            struct quad *q;
            zarray_get_volatile(quads, i, &q);

            float rgb[3];
            int bias = 100;

            for (int i = 0; i < 3; i++)
                rgb[i] = bias + (random() % (255-bias));

            fprintf(f, "%f %f %f setrgbcolor\n", rgb[0]/255.0f, rgb[1]/255.0f, rgb[2]/255.0f);
            fprintf(f, "%.15f %.15f moveto %.15f %.15f lineto %.15f %.15f lineto %.15f %.15f lineto %.15f %.15f lineto stroke\n",
                    q->p[0][0], q->p[0][1],
                    q->p[1][0], q->p[1][1],
                    q->p[2][0], q->p[2][1],
                    q->p[3][0], q->p[3][1],
                    q->p[0][0], q->p[0][1]);
        }

        fclose(f);
    }

//        printf("  %d %d %d %d\n", indices[0], indices[1], indices[2], indices[3]);

/*
        if (td->debug) {
            for (int i = 0; i < 4; i++) {
            int i0 = indices[i];
                int i1 = indices[(i+1)&3];

                if (i1 < i0)
                    i1 += zarray_size(cluster);

                for (int j = i0; j <= i1; j++) {
                    struct pt *p;
                    zarray_get_volatile(cluster, j % zarray_size(cluster), &p);

                    edgeim->buf[p->y*edgeim->stride + p->x] = 30+64*i;
                }
            }
            } */

    unionfind_destroy(uf);

    for (int i = 0; i < zarray_size(clusters); i++) {
        zarray_t *cluster;
        zarray_get(clusters, i, &cluster);
        zarray_destroy(cluster);
    }

    zarray_destroy(clusters);

    image_u8_destroy(edgeim);

    return quads;
}
Beispiel #19
0
int vx_gtk_display_dispatch_mouse(vx_display_t * disp, vx_mouse_event_t *event)
{
    assert(disp->impl_type == VX_GTK_DISPLAY_IMPL);
    state_t * state = disp->impl;

    pthread_mutex_lock(&state->mutex);
    render_info_t * rinfo = state->last_render_info;
    if (rinfo == NULL) {
        pthread_mutex_unlock(&state->mutex);
        return 1;
    }

    {// Make a copy of the event, whose memory we will manage
        vx_mouse_event_t * tmp = event;
        event  = malloc(sizeof(vx_mouse_event_t));
        memcpy(event, tmp, sizeof(vx_mouse_event_t));
    }

    // Determine which layer is focused:
    vx_mouse_event_t * last_event = state->last_mouse_event;
    state->last_mouse_event = event;
    if (!last_event ) { //XXX what to do here? (first time)
        pthread_mutex_unlock(&state->mutex);
        return 1;
    }

    uint32_t bdiff = event->button_mask ^ last_event->button_mask;
    free(last_event);

    // 1 Each time the mouse is pushed down, the layer_id is set to the layer under the mouse
    // 2 if the mouse is not pushed down, the layer under the mouse is selected

    int layer_under_mouse_id = pick_layer(rinfo, event->x, event->y);
    if (layer_under_mouse_id == 0) {
        pthread_mutex_unlock(&state->mutex);
        return 1; // there may be no layers
    }

    int button_clicked = bdiff && (bdiff & event->button_mask);
    int button_down = event->button_mask;

    if (!button_clicked && button_down) {
        // leave the layer id as is
    } else if (layer_under_mouse_id != 0){
        state->mouse_pressed_layer_id = layer_under_mouse_id;
    } else {
        // no mouse under layer -- don't change the id?
    }
    int mouse_pressed_layer_id = state->mouse_pressed_layer_id; //local copy

    vx_camera_pos_t * mouse_pressed_layer_pos_orig = NULL;
    zhash_get(rinfo->camera_positions, &mouse_pressed_layer_id, &mouse_pressed_layer_pos_orig);
    vx_camera_pos_t * mouse_pressed_layer_pos = calloc(1,sizeof(vx_camera_pos_t)); // local copy
    memcpy(mouse_pressed_layer_pos,mouse_pressed_layer_pos_orig, sizeof(vx_camera_pos_t));

    // 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->mouse_event(linfo->event_handler, NULL, mouse_pressed_layer_pos, 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_mouse(l, mouse_pressed_layer_id, mouse_pressed_layer_pos, event);
    }
    pthread_mutex_unlock(&state->listener_mutex);
    free(mouse_pressed_layer_pos);

    return 1; //gobble all events
}
Beispiel #20
0
void vx_gtk_display_show_context_menu(vx_display_t * disp, vx_mouse_event_t * event)
{
    state_t * state = disp->impl;
    vx_camera_pos_t layer_cam_pos;

    pthread_mutex_lock(&state->mutex);
    state->popup_layer_id = pick_layer(state->last_render_info, event->x, event->y);
    vx_camera_pos_t * pos = NULL;
    zhash_get(state->last_render_info->camera_positions, &state->popup_layer_id, &pos);
    if (pos != NULL)
        memcpy(&layer_cam_pos, pos, sizeof(vx_camera_pos_t));
    pthread_mutex_unlock(&state->mutex);

    if (state->popup_layer_id == 0)
        return;

    layer_info_t * linfo = NULL;
    zhash_get(state->layer_info_map, &state->popup_layer_id, &linfo);


    GtkWidget * menu = gtk_menu_new();

    // Camera buttons
    {
        GtkWidget * labelwrapper = gtk_menu_item_new();
        GtkWidget * label = gtk_label_new("Foo");
        gtk_label_set_markup(GTK_LABEL(label), "<b>Camera options</b>");
        gtk_container_add(GTK_CONTAINER(labelwrapper), label); // Auto centers? I guess that's fine
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), labelwrapper);

        GtkWidget * resetCam = gtk_menu_item_new_with_label("Reset Camera");
        g_signal_connect(resetCam, "activate", (GCallback) menu_action_reset_camera, state);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), resetCam);

        GtkWidget * button1 = gtk_check_menu_item_new_with_label ("Perspective projection");
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), button1);
        gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(button1), 1);

        GtkWidget * button2 = gtk_check_menu_item_new_with_label ("Orthographic projection");
        gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(button2), 1);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), button2);

        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (layer_cam_pos.perspectiveness == 1.0 ? button1 : button2), TRUE);

        g_signal_connect(button1, "activate",
                         (GCallback) menu_action_perspective, state);
        g_signal_connect(button2, "activate",
                         (GCallback) menu_action_ortho, state);

        // Interface modes
        GtkWidget * iface_wrapper = gtk_menu_item_new_with_label("Interface mode");
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), iface_wrapper);
        {
            GtkWidget * iface_menu = gtk_menu_new();
            gtk_menu_item_set_submenu(GTK_MENU_ITEM(iface_wrapper), iface_menu);

            GtkWidget * iface_20d = gtk_check_menu_item_new_with_label("2.0D");
            gtk_menu_shell_append(GTK_MENU_SHELL(iface_menu), iface_20d);
            gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(iface_20d), 1);

            GtkWidget * iface_25d = gtk_check_menu_item_new_with_label("2.5D");
            gtk_menu_shell_append(GTK_MENU_SHELL(iface_menu), iface_25d);
            gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(iface_25d), 1);

            GtkWidget * iface_30d = gtk_check_menu_item_new_with_label("3.0D");
            gtk_menu_shell_append(GTK_MENU_SHELL(iface_menu), iface_30d);
            gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(iface_30d), 1);

            float iface = default_cam_mgr_get_interface_mode(linfo->cam_mgr);
            GtkWidget * active = NULL;
            if (iface ==  2.0f) {
                active = iface_20d;
            } else if (iface ==  2.5f) {
                active = iface_25d;
            } else if (iface == 3.0f) {
                active = iface_30d;
            } else {
                printf("WRN: iface mode %f not supported by menu!\n", iface);
                active = iface_25d;
            }
            gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (active), TRUE);


            g_signal_connect(iface_20d, "activate", (GCallback) menu_action_iface_20d, state);
            g_signal_connect(iface_25d, "activate", (GCallback) menu_action_iface_25d, state);
            g_signal_connect(iface_30d, "activate", (GCallback) menu_action_iface_30d, state);

        }


    }

    {
        GtkWidget * labelwrapper = gtk_menu_item_new();
        GtkWidget * label = gtk_label_new("Foo");
        gtk_label_set_markup(GTK_LABEL(label), "<b>Display Options</b>");
        gtk_container_add(GTK_CONTAINER(labelwrapper), label); // Auto centers? I guess that's fine
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), labelwrapper);

        GtkWidget * showBM = gtk_menu_item_new_with_label("Show Buffer/Layer Manager");
        g_signal_connect(showBM, "activate",(GCallback) menu_action_buffer_manager, state);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), showBM);

        GtkWidget * scene = gtk_menu_item_new_with_label("Save Vx Scene");
        g_signal_connect(scene, "activate",(GCallback) menu_action_scene, state);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), scene);

        GtkWidget * shot = gtk_menu_item_new_with_label("Save Screenshot");
        g_signal_connect(shot, "activate",(GCallback) menu_action_screen_shot, state);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), shot);

        if (state->movie_file == NULL) {
            GtkWidget * movie = gtk_menu_item_new_with_label("Record movie");
            g_signal_connect(movie, "activate",(GCallback) menu_action_record_movie, state);
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), movie);
        } else {
            GtkWidget * movie = gtk_menu_item_new_with_label("Stop movie");
            g_signal_connect(movie, "activate",(GCallback) menu_action_stop_movie, state);
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), movie);
        }

    }


    gtk_widget_show_all(menu);

    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
                   /* (event != NULL) ? event->button : 0, */
                   0,
                   gtk_get_current_event_time());
    //gdk_event_get_time((GdkEvent*)event));
}
Beispiel #21
0
void process_camera_codes(state_t * state, vx_code_input_stream_t * cins)
{
    int layer_id = cins->read_uint32(cins);
    int op = cins->read_uint32(cins);

    layer_info_t * linfo = NULL;
    zhash_get(state->layer_info_map, &layer_id, &linfo);
    if (linfo == NULL)
        return;

    uint64_t mtime;
    vx_camera_pos_t * cur_pos;

    if (verbose) printf("Op %d remaining %d\n",op,  vx_code_input_stream_available(cins));

    double eyedf[3];
    double lookatdf[3];
    double updf[3];
    double xy0[2];
    double xy1[2];

    switch(op) {
        case OP_DEFAULTS:
            default_cam_mgr_defaults(linfo->cam_mgr, UI_ANIMATE_MS);
            break;

        case OP_PROJ_PERSPECTIVE:
        case OP_PROJ_ORTHO:
            cur_pos = default_cam_mgr_get_cam_target(linfo->cam_mgr,&mtime);
            cur_pos->perspectiveness = op == OP_PROJ_ORTHO ? 0.0f : 1.0f;
            default_cam_mgr_set_cam_pos(linfo->cam_mgr, cur_pos, 0, 0);
            vx_camera_pos_destroy(cur_pos);
            break;

        case OP_LOOKAT:
            eyedf[0] = cins->read_float(cins);
            eyedf[1] = cins->read_float(cins);
            eyedf[2] = cins->read_float(cins);

            lookatdf[0] = cins->read_float(cins);
            lookatdf[1] = cins->read_float(cins);
            lookatdf[2] = cins->read_float(cins);

            updf[0] = cins->read_float(cins);
            updf[1] = cins->read_float(cins);
            updf[2] = cins->read_float(cins);
            mtime = cins->read_uint32(cins); // animate ms ignored! XXX

            default_cam_mgr_lookat(linfo->cam_mgr, eyedf, lookatdf, updf, cins->read_uint8(cins), mtime);
            break;

        case OP_FIT2D:
            xy0[0] = cins->read_float(cins);
            xy0[1] = cins->read_float(cins);

            xy1[0] = cins->read_float(cins);
            xy1[1] = cins->read_float(cins);
            mtime = cins->read_uint32(cins); // animate ms ignored! XXX

            default_cam_mgr_fit2D(linfo->cam_mgr, xy0, xy1, cins->read_uint8(cins), mtime);
            break;
        case OP_FOLLOW_MODE_DISABLE:
            default_cam_mgr_follow_disable(linfo->cam_mgr);

            break;

        case OP_INTERFACE_MODE:
        {
            float mode = cins->read_float(cins);
            default_cam_mgr_set_interface_mode(linfo->cam_mgr, mode);
        }
    }

    if (op == OP_FOLLOW_MODE) {
        double pos3[3];
        double quat4[4];

        pos3[0] = cins->read_double(cins);
        pos3[1] = cins->read_double(cins);
        pos3[2] = cins->read_double(cins);

        quat4[0] = cins->read_double(cins);
        quat4[1] = cins->read_double(cins);
        quat4[2] = cins->read_double(cins);
        quat4[3] = cins->read_double(cins);

        int followYaw = cins->read_uint32(cins);
        uint32_t animate_ms = cins->read_uint32(cins);

        default_cam_mgr_follow(linfo->cam_mgr, pos3, quat4, followYaw, animate_ms);
    }
}
Beispiel #22
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);

}
Beispiel #23
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");
    }
}
Beispiel #24
0
static void * run_process(void * data)
{
    vx_world_t * world = data;


    while (world->process_running) {
        vx_world_listener_t * listener = NULL;
        char * buffer_name = NULL;

        // 1) Wait until there's data
        pthread_mutex_lock(&world->queue_mutex);
        while (zarray_size(world->buffer_queue) == 0 && zarray_size(world->listener_queue) == 0 && world->process_running) {
            pthread_cond_wait(&world->queue_cond, &world->queue_mutex);
        }

        if (!world->process_running) { // XXX cleaning out the queue?
            pthread_mutex_unlock(&world->queue_mutex);
            break;
        }

        // Processing new listeners takes priority
        if ( zarray_size(world->listener_queue) > 0) {
            zarray_get(world->listener_queue, 0, &listener);
            zarray_remove_index(world->listener_queue, 0, 0);
        } else {
            assert(zarray_size(world->buffer_queue) > 0);
            zarray_get(world->buffer_queue, 0, &buffer_name);
            zarray_remove_index(world->buffer_queue, 0, 0);
        }
        pthread_mutex_unlock(&world->queue_mutex);

        // Operation A: New listener
        if (listener != NULL) {
            // re-transmit each buffer that has already been serialized
            pthread_mutex_lock(&world->buffer_mutex);
            zhash_iterator_t itr;
            zhash_iterator_init(world->buffer_map, &itr);
            char * name = NULL;
            vx_buffer_t * buffer = NULL;
            while(zhash_iterator_next(&itr, &name, &buffer)) {
                if (buffer->front_codes->pos != 0) {
                    vx_code_output_stream_t * bresc_codes = make_buffer_resource_codes(buffer, buffer->front_resc);

                    // Doing a swap in 3 steps (instead of 4) like this
                    // is only safe if the listener is brand new, which we are
                    // guaranteed is the case in this chunk of code
                    listener->send_codes(listener, bresc_codes->data, bresc_codes->pos);
                    listener->send_resources(listener, buffer->front_resc);
                    listener->send_codes(listener, buffer->front_codes->data, buffer->front_codes->pos);

                    vx_code_output_stream_destroy(bresc_codes);
                }
            }

            pthread_mutex_unlock(&world->buffer_mutex);
        }

        // Operation B: buffer swap
        if (buffer_name != NULL) {
            vx_buffer_t * buffer = NULL;
            pthread_mutex_lock(&world->buffer_mutex);
            zhash_get(world->buffer_map, &buffer_name, &buffer);
            pthread_mutex_unlock(&world->buffer_mutex);

            delayed_swap(buffer);
        }

    }

    pthread_exit(NULL);
}