Beispiel #1
0
void
adrt_slave_work(tienet_buffer_t *work, tienet_buffer_t *result)
{
    TIE_3 pos, foc;
    unsigned char rm, op;
    uint32_t ind, wlen;
    uint16_t wid;

    /* Length of work data */
    wlen = work->ind;
    ind = 0;

    /* Get work type */
    TCOPY(uint8_t, work->data, ind, &op, 0);
    ind += 1;

    /* Workspace ID */
    TCOPY(uint16_t, work->data, ind, &wid, 0);
    ind += 2;

    /* This will get improved later with caching */
    TIENET_BUFFER_SIZE((*result), 3); /* Copy op and wid, 3 bytes */
    memcpy(result->data, &work->data[0], 3);
    result->ind = ind;

    switch (op) {
	case ADRT_WORK_INIT:
	{
	    render_camera_init (&adrt_workspace_list[wid].camera, adrt_slave_threads);
	    if ( slave_load (&adrt_workspace_list[wid].tie, (void *)work->data, wlen-ind) != 0 )
		bu_exit (1, "Failed to load geometry. Going into a flaming tailspin\n");
	    tie_prep (&adrt_workspace_list[wid].tie);
	    render_camera_prep (&adrt_workspace_list[wid].camera);
	    printf ("ready.\n");
	    result->ind = 0;

	    /* Mark the workspace as active so it can be cleaned up when the time comes. */
	    adrt_workspace_list[wid].active = 1;
	}
	break;

	case ADRT_WORK_STATUS:
	{
#ifdef HAVE_GETLOADAVG
	    double loadavg = -1.0;
	    getloadavg (&loadavg, 1);
	    printf ("load average: %f\n", loadavg);
#endif
	}
	break;

	case ADRT_WORK_SELECT:
	{
	    uint8_t c;
	    char string[255];
	    uint32_t n, i, num;

	    ind = 1;	/* ind is too far in for some reason, force it back to 1? */

	    /* reset */
	    TCOPY(uint8_t, work->data, ind, &c, 0);
	    ind += 1;
	    if (c)
		for (i = 0; i < slave_load_mesh_num; i++)
		    slave_load_mesh_list[i].flags = 0;

	    /* number of strings to match */
	    TCOPY(uint32_t, work->data, ind, &num, 0);
	    ind += 4;

	    for (i = 0; i < num; i++) {
		/* string length */
		TCOPY(uint8_t, work->data, ind, &c, 0);	/* this likes to break, 'num' is way too big. */
		ind += 1;

		/* string */
		memcpy(string, &work->data[ind], c);
		ind += c;

		/* set select flag */
		for (n = 0; n < slave_load_mesh_num; n++)
		    if (strstr(slave_load_mesh_list[n].name, string) || c == 1)
			slave_load_mesh_list[n].flags = (slave_load_mesh_list[n].flags & 0x1) | ((slave_load_mesh_list[n].flags & 0x2) ^ 0x2);
	    }

	    /* zero length result */
	    result->ind = 0;
	}
	break;

	case ADRT_WORK_SHOTLINE:
	{
	    tie_ray_t ray;
	    void *mesg;
	    int dlen;

	    mesg = NULL;

	    /* coordinates */
	    TCOPY(TIE_3, work->data, ind, ray.pos.v, 0);
	    ind += sizeof (TIE_3);
	    TCOPY(TIE_3, work->data, ind, ray.dir.v, 0);
	    ind += sizeof (TIE_3);

	    /* Fire the shot */
	    ray.depth = 0;
	    render_util_shotline_list (&adrt_workspace_list[wid].tie, &ray, &mesg, &dlen);

	    /* Make room for shot data */
	    TIENET_BUFFER_SIZE((*result), result->ind + dlen + 2*sizeof (TIE_3));
	    memcpy(&result->data[result->ind], mesg, dlen);
	    result->ind += dlen;

	    TCOPY(TIE_3, &ray.pos, 0, result->data, result->ind);
	    result->ind += sizeof (TIE_3);

	    TCOPY(TIE_3, &ray.dir, 0, result->data, result->ind);
	    result->ind += sizeof (TIE_3);

	    free (mesg);
	}
	break;

	case ADRT_WORK_SPALL:
	{
#if 0
	    tie_ray_t ray;
	    tfloat angle;
	    void *mesg;
	    int dlen;

	    mesg = NULL;

	    /* position */
	    TCOPY(TIE_3, data, ind, &ray.pos, 0);
	    ind += sizeof (TIE_3);

	    /* direction */
	    TCOPY(TIE_3, data, ind, &ray.dir, 0);
	    ind += sizeof (TIE_3);

	    /* angle */
	    TCOPY(tfloat, data, ind, &angle, 0);
	    ind += sizeof (tfloat);

	    /* Fire the shot */
	    ray.depth = 0;
	    render_util_spall_list(tie, &ray, angle, &mesg, &dlen);

	    /* Make room for shot data */
	    *res_len = sizeof (common_work_t) + dlen;
	    *res_buf = (void *)realloc(*res_buf, *res_len);

	    ind = 0;

	    memcpy(&((char *)*res_buf)[ind], mesg, dlen);

	    free (mesg);
#endif
	}
	break;

	case ADRT_WORK_FRAME_ATTR:
	{
	    uint16_t image_w, image_h, image_format;

	    /* Image Size */
	    TCOPY(uint16_t, work->data, ind, &image_w, 0);
	    ind += 2;
	    TCOPY(uint16_t, work->data, ind, &image_h, 0);
	    ind += 2;
	    TCOPY(uint16_t, work->data, ind, &image_format, 0);
	    ind += 2;

	    adrt_workspace_list[wid].camera.w = image_w;
	    adrt_workspace_list[wid].camera.h = image_h;
	    render_camera_prep (&adrt_workspace_list[wid].camera);
	    result->ind = 0;
	}
	break;

	case ADRT_WORK_FRAME:
	{
	    camera_tile_t tile;
	    uint8_t type;
	    tfloat fov;

	    /* Camera type */
	    TCOPY(uint8_t, work->data, ind, &type, 0);
	    ind += 1;

	    /* Camera fov */
	    TCOPY(tfloat, work->data, ind, &fov, 0);
	    ind += sizeof (tfloat);

	    /* Camera position */
	    TCOPY(TIE_3, work->data, ind, &pos, 0);
	    ind += sizeof (TIE_3);

	    /* Camera Focus */
	    TCOPY(TIE_3, work->data, ind, &foc, 0);
	    ind += sizeof (TIE_3);

	    /* Update Rendering Method if it has Changed */
	    rm = work->data[ind];
	    ind += 1;

	    if (rm != adrt_workspace_list[wid].camera.rm || ADRT_MESSAGE_MODE_CHANGEP(rm)) {
		rm = ADRT_MESSAGE_MODE(rm);

		adrt_workspace_list[wid].camera.render.free (&adrt_workspace_list[wid].camera.render);

		switch (rm) {
		    case RENDER_METHOD_DEPTH:
			render_depth_init(&adrt_workspace_list[wid].camera.render, NULL);
			break;

		    case RENDER_METHOD_COMPONENT:
			render_component_init(&adrt_workspace_list[wid].camera.render, NULL);
			break;

		    case RENDER_METHOD_FLOS:
		    {
			TIE_3 frag_pos;
			char buf[BUFSIZ];

			/* Extract shot position and direction */
			TCOPY(TIE_3, work->data, ind, &frag_pos, 0);
			snprintf(buf, BUFSIZ, "#(%f %f %f)", V3ARGS(frag_pos.v));
			ind += sizeof (TIE_3);
			render_flos_init(&adrt_workspace_list[wid].camera.render, buf);
		    }
		    break;

		    case RENDER_METHOD_GRID:
			render_grid_init(&adrt_workspace_list[wid].camera.render, NULL);
			break;

		    case RENDER_METHOD_NORMAL:
			render_normal_init(&adrt_workspace_list[wid].camera.render, NULL);
			break;

		    case RENDER_METHOD_PATH:
			render_path_init(&adrt_workspace_list[wid].camera.render, "12");
			break;

		    case RENDER_METHOD_PHONG:
			render_phong_init(&adrt_workspace_list[wid].camera.render, NULL);
			break;

		    case RENDER_METHOD_CUT:
			render_cut_init(&adrt_workspace_list[wid].camera.render, (char *)work->data + ind);
			break;

		    case RENDER_METHOD_SPALL:
		    {
			TIE_3 shot_pos, shot_dir;
			tfloat angle;
			char buf[BUFSIZ];

			/* Extract shot position and direction */
			TCOPY(TIE_3, work->data, ind, &shot_pos, 0);
			ind += sizeof (TIE_3);

			TCOPY(TIE_3, work->data, ind, &shot_dir, 0);
			ind += sizeof (TIE_3);

			TCOPY(tfloat, work->data, ind, &angle, 0);
			ind += sizeof (tfloat);

			snprintf(buf, BUFSIZ, "(%g %g %g) (%g %g %g) %g", V3ARGS(shot_pos.v), V3ARGS(shot_dir.v), angle);

			render_spall_init (&adrt_workspace_list[wid].camera.render, buf);
		    }
		    break;

		    default:
			break;
		}

		adrt_workspace_list[wid].camera.rm = rm;
	    }

	    /* The portion of the image to be rendered */
	    ind = work->ind - sizeof (camera_tile_t);
	    TCOPY(camera_tile_t, work->data, ind, &tile, 0);
	    ind += sizeof (camera_tile_t);

	    /* Update camera if different frame */
	    if (tile.frame != adrt_workspace_list[wid].last_frame) {
		adrt_workspace_list[wid].camera.type = type;
		adrt_workspace_list[wid].camera.fov = fov;
		adrt_workspace_list[wid].camera.pos = pos;
		adrt_workspace_list[wid].camera.focus = foc;
		render_camera_prep (&adrt_workspace_list[wid].camera);
	    }
	    adrt_workspace_list[wid].last_frame = tile.frame;

	    render_camera_render (&adrt_workspace_list[wid].camera, &adrt_workspace_list[wid].tie, &tile, result);
	}
	break;

	case ADRT_WORK_MINMAX:
	{
	    TCOPY(TIE_3, &adrt_workspace_list[wid].tie.min, 0, result->data, result->ind);
	    result->ind += sizeof (TIE_3);

	    TCOPY(TIE_3, &adrt_workspace_list[wid].tie.max, 0, result->data, result->ind);
	    result->ind += sizeof (TIE_3);
	}
	break;

	default:
	    break;
    }

#if 0
    {
	struct timeval	tv;
	static int      adrt_slave_completed = 0;
	static time_t	adrt_slave_startsec = 0;

	if (adrt_slave_startsec == 0)
	    adrt_slave_startsec = time(NULL);

	gettimeofday(&tv, NULL);
	printf("\t[Work Units Completed: %.6d  Rays: %.5d k/sec %lld]\n",
		++adrt_slave_completed,
		(int) ((tfloat) adrt_workspace_list[wid].tie.rays_fired / (tfloat) (1000 * (tv.tv_sec - adrt_slave_startsec + 1))),
		adrt_workspace_list[wid].tie.rays_fired);
	fflush(stdout);
    }
#endif

    return;
}
Beispiel #2
0
int
render_cut_init(render_t *render, const char *buf)
{
    int i;
    render_cut_t *d;
    static TIE_3 list[6];
	TIE_3 **tlist;
    vect_t up, ray_pos, ray_dir;
    fastf_t shot_len = 100, shot_width = .02;
    struct tie_id_s id;
    struct tie_ray_s ray;
    double step, f[6];

    if(buf == NULL)
	    return -1;

    sscanf(buf, "#(%lf %lf %lf) #(%lf %lf %lf)",
	    f, f+1, f+2,
	    f+3, f+3+1, f+3+2);
	VMOVE(ray_pos, f);
	VMOVE(ray_dir, f);
    VUNITIZE(ray_dir);

    shot_width = 0.01 * render->tie->radius;
    {
	vect_t v;

	VSUB2(v, ray_pos, render->tie->mid);
	shot_len = 2.0 * render->tie->radius + MAGNITUDE(v) - render->tie->radius;;
    }

    /*
     * fire through the entire geometry, marking each intersected mesh with
     * ADRT_MESH_HIT
     */
    VMOVE(ray.pos, ray_pos);
    VMOVE(ray.dir, ray_dir);
    ray.depth = 0;
    tie_work(render->tie, &ray, &id, render_cut_hit_cutline, &step);

    /* prepare cut stuff */
    tlist = (TIE_3 **)bu_malloc(sizeof(TIE_3 *) * 6, "cutting plane triangles");

    render->work = render_cut_work;
    render->free = render_cut_free;

    BU_ALLOC(render->data, render_cut_t);
    d = (render_cut_t *)render->data;

    VMOVE(d->ray_pos, ray_pos);
    VMOVE(d->ray_dir, ray_dir);

    /* Calculate the normal to be used for the plane */
    VSET(up, 0, 0, 1);
    VCROSS(d->plane,  ray_dir,  up);
    VUNITIZE(d->plane);

    /* Construct the plane */
    d->plane[3] = -VDOT( d->plane,  ray_pos); /* up is really new ray_pos */

    /* generate the shtuff for the blue line */
    tie_init(&d->tie, 2, TIE_KDTREE_FAST);

    /* Triangle 1 */
    VSET(list[0].v, ray_pos[0], ray_pos[1], ray_pos[2] - shot_width);
    VSET(list[1].v, ray_pos[0] + shot_len*ray_dir[0], ray_pos[1] + shot_len*ray_dir[1], ray_pos[2] + shot_len*ray_dir[2] - shot_width);
    VSET(list[2].v, ray_pos[0] + shot_len*ray_dir[0], ray_pos[1] + shot_len*ray_dir[1], ray_pos[2] + shot_len*ray_dir[2] + shot_width);

    /* Triangle 2 */
    VMOVE(list[3].v, ray_pos);
    list[3].v[2] -= shot_width;

    VSET(list[4].v, ray_pos[0] + shot_len*ray_dir[0], ray_pos[1] + shot_len*ray_dir[1], ray_pos[2] + shot_len*ray_dir[2] + shot_width);

    VMOVE(list[5].v, ray_pos);
    list[5].v[2] += shot_width;

    for(i=0;i<6;i++)
	tlist[i] = &list[i];

    tie_push(&d->tie, tlist, 2, NULL, 0);

    tie_prep(&d->tie);
    bu_free(tlist, "cutting plane triangles");
    return 0;
}
int
render_spall_init(render_t *render, const char *buf)
{
    struct render_spall_s *d;
    vect_t *tri_list, *vec_list, normal, up;
    fastf_t plane[4], angle;
    int i;

    /* intentionally double for scan */
    double ray_pos[3], ray_dir[3];
    double scan;

    if (buf == NULL)
	return -1;

    render->work = render_spall_work;
    render->free = render_spall_free;

    bu_sscanf(buf, "(%lg %lg %lg) (%lg %lg %lg) %lg",
	      &ray_pos[0], &ray_pos[1], &ray_pos[2],
	      &ray_dir[0], &ray_dir[1], &ray_dir[2],
	      &scan);
    angle = scan; /* double to fastf_t */

    BU_ALLOC(render->data, struct render_spall_s);
    d = (struct render_spall_s *)render->data;

    VMOVE(d->ray_pos, ray_pos);
    VMOVE(d->ray_dir, ray_dir);

    tie_init(&d->tie, TESSELLATION, TIE_KDTREE_FAST);

    /* Calculate the normal to be used for the plane */
    up[0] = 0;
    up[1] = 0;
    up[2] = 1;

    VCROSS(normal,  ray_dir,  up);
    VUNITIZE(normal);

    /* Construct the plane */
    d->plane[0] = normal[0];
    d->plane[1] = normal[1];
    d->plane[2] = normal[2];
    plane[3] = VDOT(normal,  ray_pos); /* up is really new ray_pos */
    d->plane[3] = -plane[3];

    /******************/
    /* The spall Cone */
    /******************/
    vec_list = (vect_t *)bu_malloc(sizeof(vect_t) * TESSELLATION, "vec_list");
    tri_list = (vect_t *)bu_malloc(sizeof(vect_t) * TESSELLATION * 3, "tri_list");

    render_util_spall_vec(d->ray_dir, angle, TESSELLATION, vec_list);

    /* triangles to approximate */
    for (i = 0; i < TESSELLATION; i++) {
	VMOVE(tri_list[3*i+0], ray_pos);

	VSCALE(tri_list[3*i+1],  vec_list[i],  SPALL_LEN);
	VADD2(tri_list[3*i+1],  tri_list[3*i+1],  ray_pos);

	if (i == TESSELLATION - 1) {
	    VSCALE(tri_list[3*i+2],  vec_list[0],  SPALL_LEN);
	    VADD2(tri_list[3*i+2],  tri_list[3*i+2],  ray_pos);
	} else {
	    VSCALE(tri_list[3*i+2],  vec_list[i+1],  SPALL_LEN);
	    VADD2(tri_list[3*i+2],  tri_list[3*i+2],  ray_pos);
	}
    }

/*  tie_push(&d->tie, tri_list, TESSELLATION, NULL, 0);   */
    tie_prep(&d->tie);

    bu_free(vec_list, "vec_list");
    bu_free(tri_list, "tri_list");
    return 0;
}
Beispiel #4
0
void bench(char* proj, int cache, int image) {
    struct sockaddr_in server;
    struct sockaddr_in client;
    struct hostent h;
    int i, res_len, client_socket;
    common_work_t work;
    void *res_buf;
    unsigned char *image24;
    clock_t ticks1, ticks2, ticks3;
    tfloat t;


    ticks1 = clock();
    tienet_sem_init(&bench_net_sem, 0);

    printf("loading and prepping ...\n");
    /* Camera with no threads */
    util_camera_init(&camera, 1);

    /* Parse Env Data */
    common_db_load(&db, proj);

    /*
     * Hack the environment settings to make it think there is no cache file
     * if the user is generating one, otherwise it never generates one
     */
    if (cache)
	db.env.kdtree_cache_file[0] = 0;

    /* Read the data off disk and pack it */
    app_size = common_pack(&db, &app_data, proj);

    /* Launch a networking thread to do ipc data streaming */
    pthread_create(&bench_thread, NULL, bench_ipc, 0);

    /* Parse the data into memory for rendering */
    /* create a socket */
    if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
	fprintf(stderr, "unable to create socket, exiting.\n");
	exit(1);
    }

    /* Bind any available port number */
    client.sin_family = AF_INET;
    client.sin_addr.s_addr = htonl(INADDR_ANY);
    client.sin_port = htons(0);

    if (bind(client_socket, (struct sockaddr *)&client, sizeof(client)) < 0) {
	fprintf(stderr, "unable to bind socket, exiting\n");
	exit(1);
    }

    /* Establish ipc connection */
    if (gethostbyname("localhost")) {
	h = gethostbyname("localhost")[0];
    } else {
	fprintf(stderr, "unknown host: %s\n", "localhost");
	exit(1);
    }

    server.sin_family = h.h_addrtype;
    memcpy((char *)&server.sin_addr.s_addr, h.h_addr_list[0], h.h_length);
    server.sin_port = htons(LOCAL_PORT);

    tienet_sem_wait(&bench_net_sem);
    if (connect(client_socket, (struct sockaddr *)&server, sizeof(server)) < 0) {
	fprintf(stderr, "cannot establish connection, exiting.\n");
	exit(1);
    }

    /* stream and unpack the data */
    common_unpack(&db, &tie, &camera, client_socket);
    tie_prep(&tie);

    /* Prep */
    common_env_prep(&db.env);
    util_camera_prep(&camera, &db);

    /* Allocate memory for a frame */
    bench_frame = malloc(4 * sizeof(tfloat) * db.env.img_w * db.env.img_h);
    if (!bench_frame) {
	perror("bench_frame");
	exit(1);
    }
    memset(bench_frame, 0, 4 * sizeof(tfloat) * db.env.img_w * db.env.img_h);

    /* Render an image */
    work.orig_x = 0;
    work.orig_y = 0;
    work.size_x = db.env.img_w;
    work.size_y = db.env.img_h;
    work.format = COMMON_BIT_DEPTH_24;

    printf("rendering ...\n");
    res_buf = NULL;
    ticks2 = clock();
    util_camera_render(&camera, &db, &tie, &work, sizeof(common_work_t), &res_buf, &res_len);
    ticks3 = clock();

    printf("prep   time: %.3f sec\n", (tfloat)(ticks2 - ticks1) / (tfloat)CLOCKS_PER_SEC);
    t = (tfloat)(ticks3 - ticks2) / (tfloat)CLOCKS_PER_SEC;
    printf("render time: %.3f sec\n", t);
    printf("rays /  sec: %d\n", (int)((db.env.img_w * db.env.img_h) / t));
    if (image) {
	image24 = &((unsigned char *)res_buf)[sizeof(common_work_t)];
	util_image_save_ppm("dump.ppm", image24, db.env.img_w, db.env.img_h);
    }

    close(client_socket);

    util_camera_free(&camera);
    free(app_data);
    free(bench_frame);
    common_unpack_free(&db);

    if (cache) {
	void *kdcache;
	unsigned int size;
	FILE *fh;

	tie_kdtree_cache_free(&tie, &kdcache);
	memcpy(&size, kdcache, sizeof(unsigned int));
	printf("saving kd-tree cache: %d bytes\n", size);
	fh = fopen("kdtree.cache", "wb");
	fwrite(kdcache, size, 1, fh);
	fclose(fh);
	free(kdcache);
    }
}