예제 #1
0
파일: sh_fbm.c 프로젝트: cciechad/brlcad
/*
 *	F B M _ R E N D E R
 */
int
fbm_render(struct application *ap, struct partition *pp, struct shadework *swp, char *dp)
{
    register struct fbm_specific *fbm_sp =
	(struct fbm_specific *)dp;
    vect_t v_noise;
    point_t pt;

    if (rdebug&RDEBUG_SHADE)
	bu_struct_print( "foo", fbm_parse, (char *)fbm_sp );

    pt[0] = swp->sw_hit.hit_point[0] * fbm_sp->scale[0];
    pt[1] = swp->sw_hit.hit_point[1] * fbm_sp->scale[1];
    pt[2] = swp->sw_hit.hit_point[2] * fbm_sp->scale[2];

    bn_noise_vec(pt, v_noise);

    VSCALE(v_noise, v_noise, fbm_sp->distortion);

    if (rdebug&RDEBUG_SHADE)
	bu_log("fbm_render: point (%g %g %g) becomes (%g %g %g)\n\tv_noise (%g %g %g)\n",
	       V3ARGS(swp->sw_hit.hit_point),
	       V3ARGS(pt),
	       V3ARGS(v_noise));

    VADD2(swp->sw_hit.hit_normal, swp->sw_hit.hit_normal, v_noise);
    VUNITIZE(swp->sw_hit.hit_normal);

    return(1);
}
/*
 * This routine is called (at prep time)
 * once for each region which uses this shader.
 * Any shader-specific initialization should be done here.
 *
 * Returns:
 * 1 success
 * 0 success, but delete region
 * -1 failure
 */
HIDDEN int
toon_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip)


/* pointer to reg_udata in *rp */

/* New since 4.4 release */
{
    register struct toon_specific *toon_sp;

    /* check the arguments */
    RT_CHECK_RTI(rtip);
    BU_CK_VLS(matparm);
    RT_CK_REGION(rp);

    if (rdebug&RDEBUG_SHADE)
	bu_log("toon_setup(%s)\n", rp->reg_name);

    /* Get memory for the shader parameters and shader-specific data */
    BU_GET(toon_sp, struct toon_specific);
    *dpp = toon_sp;

    /* initialize the default values for the shader */
    memcpy(toon_sp, &toon_defaults, sizeof(struct toon_specific));

    /* parse the user's arguments for this use of the shader. */
    if (bu_struct_parse(matparm, toon_parse_tab, (char *)toon_sp, NULL) < 0)
	return -1;

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print(" Parameters:", toon_print_tab, (char *)toon_sp);
    }

    return 1;
}
예제 #3
0
파일: sh_spm.c 프로젝트: kanzure/brlcad
HIDDEN void
spm_print(register struct region *rp, void *dp)
{
    struct spm_specific *spm;

    spm = (struct spm_specific *)dp;

    bu_log("spm_print(rp=%p, dp = %p)\n", (void *)rp, dp);
    (void)bu_struct_print("spm_print", spm_parse, (char *)dp);
    if (spm->sp_map) bn_spm_dump(spm->sp_map, 0);
}
예제 #4
0
파일: sh_text.c 프로젝트: kanzure/brlcad
HIDDEN int
txt_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
{
    register struct txt_specific *tp;
    int pixelbytes = 3;

    BU_CK_VLS(matparm);
    BU_GET(tp, struct txt_specific);
    *dpp = tp;

    bu_vls_init(&tp->tx_name);

    /* defaults */
    tp->tx_w = tp->tx_n = -1;
    tp->tx_trans_valid = 0;
    tp->tx_scale[X] = 1.0;
    tp->tx_scale[Y] = 1.0;
    tp->tx_mirror = 0;
    tp->tx_datasrc = 0; /* source is auto-located by default */
    tp->tx_binunifp = NULL;
    tp->tx_mp = NULL;

    /* load given values */
    if (bu_struct_parse(matparm, txt_parse, (char *)tp) < 0) {
	BU_PUT(tp, struct txt_specific);
	return -1;
    }

    /* validate values */
    if (tp->tx_w < 0) tp->tx_w = 512;
    if (tp->tx_n < 0) tp->tx_n = tp->tx_w;
    if (tp->tx_trans_valid) rp->reg_transmit = 1;
    BU_CK_VLS(&tp->tx_name);
    if (bu_vls_strlen(&tp->tx_name) <= 0) return -1;
    /* !?! if (tp->tx_name[0] == '\0') return -1;	*/ /* FAIL, no file */

    if (BU_STR_EQUAL(mfp->mf_name, "bwtexture")) pixelbytes = 1;

    /* load the texture from its datasource */
    if (txt_load_datasource(tp, rtip->rti_dbip, tp->tx_w * tp->tx_n * pixelbytes)<0) {
	bu_log("\nERROR: txt_setup() %s %s could not be loaded [source was %s]\n", rp->reg_name, bu_vls_addr(&tp->tx_name), tp->tx_datasrc==TXT_SRC_OBJECT?"object":tp->tx_datasrc==TXT_SRC_FILE?"file":"auto");
	return -1;
    }


    if (rdebug & RDEBUG_SHADE) {
	bu_log("txt_setup: texture loaded!  type=%s name=%s\n", tp->tx_datasrc==TXT_SRC_AUTO?"auto":tp->tx_datasrc==TXT_SRC_OBJECT?"object":tp->tx_datasrc==TXT_SRC_FILE?"file":"unknown", bu_vls_addr(&tp->tx_name));
	bu_struct_print("texture", txt_parse, (char *)tp);
    }

    return 1;				/* OK */
}
HIDDEN int osl_setup(register struct region *rp, struct bu_vls *matparm,
		     void **dpp, const struct mfuncs *mfp,
		     struct rt_i *rtip)
{
    register struct osl_specific *osl_sp;

    /* check the arguments */
    RT_CHECK_RTI(rtip);
    BU_CK_VLS(matparm);
    RT_CK_REGION(rp);

    if (rdebug&RDEBUG_SHADE)
	bu_log("osl_setup(%s)\n", rp->reg_name);

    /* Get memory for the shader parameters and shader-specific data */
    BU_GET(osl_sp, struct osl_specific);
    *dpp = (char *)osl_sp;

    /* -----------------------------------
     * Initialize the osl specific values
     * -----------------------------------
     */

    osl_sp->magic = OSL_MAGIC;

    /* Parse the user's arguments to fill osl specifics */
    ShaderGroupInfo group_info;
    if (osl_parse(matparm, group_info) < 0) {
	return -1;
    }

    /* -----------------------------------
     * Initialize osl render system
     * -----------------------------------
     */
    /* If OSL system was not initialized yet, do it */
    if (oslr == NULL) {
	oslr = new OSLRenderer();
    }
    /* Add this shader to OSL system */
    osl_sp->shader_ref = oslr->AddShader(group_info);

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print(" Parameters:", osl_print_tab, (char *)osl_sp);
    }

    return 1;
}
/*
 * This is called (from viewshade() in shade.c) once for each hit point
 * to be shaded.  The purpose here is to fill in values in the shadework
 * structure.
 */
int
toon_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
{
    int i;
    struct toon_specific *toon_sp = (struct toon_specific *)dp;
    struct light_specific *lp;
    fastf_t cosi, scale;

    /* check the validity of the arguments we got */
    RT_AP_CHECK(ap);
    RT_CHECK_PT(pp);
    CK_TOON_SP(toon_sp);

    if (rdebug&RDEBUG_SHADE)
	bu_struct_print("toon_render Parameters:", toon_print_tab, (char *)toon_sp);

    /* if surface normal is nearly orthogonal to the ray, make a black line */
    if (VDOT(swp->sw_hit.hit_normal, ap->a_inv_dir) >= 0.8) {
	VSETALL(swp->sw_color, 0);
	return 1;
    }

    /* probably need to set some swp values here to avoid the infinite recursion
     * if specified lights exist. */
    light_obs(ap, swp, MFI_HIT);

    /* Consider effects of each light source */
    for (i=ap->a_rt_i->rti_nlights-1; i>=0; i--) {
	if ((lp = (struct light_specific *)swp->sw_visible[i]) == LIGHT_NULL)
	    continue;

	cosi = VDOT(swp->sw_hit.hit_normal, swp->sw_tolight);
	if (cosi <= 0.0) scale = 0.0;
	else if (cosi <= 0.5) scale = 0.5;
	else if (cosi <= 0.8) scale = 0.8;
	else scale = 1.0;
	VSCALE(swp->sw_color, swp->sw_color, scale);
	return 1;
    }

    /* no paths to light source, so just paint it black */
    VSETALL(swp->sw_color, 0);

    if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	(void)rr_render(ap, pp, swp);
    return 1;
}
예제 #7
0
파일: sh_flat.c 프로젝트: kanzure/brlcad
/*
 * This routine is called (at prep time) once for each region which uses this
 * shader.  The shader specific flat_specific structure is allocated and
 * default values are set.  Then any user-given values override.
 */
HIDDEN int
flat_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip)
{

    register struct flat_specific *flat_sp;

    /* check the arguments */
    RT_CHECK_RTI(rtip);
    BU_CK_VLS(matparm);
    RT_CK_REGION(rp);

    if (rdebug&RDEBUG_SHADE)
	bu_log("flat_setup(%s)\n", rp->reg_name);

    /* Get memory for the shader parameters and shader-specific data */
    BU_GET(flat_sp, struct flat_specific);
    *dpp = flat_sp;

    /* color priority:
     *
     * priority goes first to the flat shader's color parameter
     * second priority is to the material color value
     * third priority is to the flat shader's default color (white)
     */

    /* initialize the default values for the shader */
    memcpy(flat_sp, &flat_defaults, sizeof(struct flat_specific));

    /* load the material color if it was set */
    if (rp->reg_mater.ma_color_valid) {
	VMOVE(flat_sp->color, rp->reg_mater.ma_color);
    }

    /* parse the user's arguments for this use of the shader. */
    if (bu_struct_parse(matparm, flat_parse_tab, (char *)flat_sp) < 0)
	return -1;

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print(" Parameters:", flat_parse_tab, (char *)flat_sp);
    }

    return 1;
}
예제 #8
0
파일: sh_fbm.c 프로젝트: cciechad/brlcad
/*
 *	F B M _ S E T U P
 */
HIDDEN int
fbm_setup(register struct region *rp, struct bu_vls *matparm, char **dpp)
{
    register struct fbm_specific *fbm;

    BU_CK_VLS( matparm );
    BU_GETSTRUCT( fbm, fbm_specific );
    *dpp = (char *)fbm;

    memcpy(fbm, &fbm_defaults, sizeof(struct fbm_specific));
    if (rdebug&RDEBUG_SHADE)
	bu_log("fbm_setup\n");

    if (bu_struct_parse( matparm, fbm_parse, (char *)fbm ) < 0 )
	return(-1);

    if (rdebug&RDEBUG_SHADE)
	bu_struct_print( rp->reg_name, fbm_parse, (char *)fbm );

    return(1);
}
예제 #9
0
파일: sh_flat.c 프로젝트: kanzure/brlcad
/*
 * This is called (from viewshade() in shade.c) once for each hit point
 * to be shaded.  The purpose here is to fill in values in the shadework
 * structure.
 *
 * The flat shader is probably the second most simple shader (second to
 * the null/invisible shader -- it does nothing).  It shades an object
 * a constant color.  The only complexity comes into play when a
 * transparency value is set.  Then we get the color value behind the
 * one we are shading and blend accordingly with the flat color.
 */
int
flat_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
{

    register struct flat_specific *flat_sp = (struct flat_specific *)dp;
    const point_t unit = {1.0, 1.0, 1.0};
    point_t intensity;

    /* check the validity of the arguments we got */
    RT_AP_CHECK(ap);
    RT_CHECK_PT(pp);
    CK_FLAT_SP(flat_sp);

    if (rdebug&RDEBUG_SHADE)
	bu_struct_print("flat_render Parameters:", flat_parse_tab, (char *)flat_sp);

    /* do the actual flat color shading for the flat object. if the object is
     * not transparent, just put the color.  if the object is transparent, do
     * a little more work determining the background pixel, and then blend with
     * the flat foreground object.
     */
    if (VNEAR_ZERO(flat_sp->transparency, SMALL_FASTF)) {

	/* just put the flat value */
	VMOVE(swp->sw_color, flat_sp->color);
    } else {

	/* this gets the background pixel value, if the transparency is not 0 */
	swp->sw_transmit = 1.0; /*!!! try to remove */
	VMOVE(swp->sw_basecolor, flat_sp->transparency);
	(void)rr_render(ap, pp, swp);

	/* now blend with the foreground object being shaded */
	VSUB2(intensity, unit, flat_sp->transparency);  /* inverse transparency is how much we want */
	VELMUL(intensity, intensity, flat_sp->color); /* ??? is there a way to merge this mul->add step? */
	VADD2(swp->sw_color, swp->sw_color, intensity);
    }

    return 1;
}
/*
 * This is called (from viewshade() in shade.c) once for each hit point
 * to be shaded.  The purpose here is to fill in values in the shadework
 * structure.
 *
 * dp is a pointer to the shader-specific struct
 */
int
bbd_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
{
    register struct bbd_specific *bbd_sp = (struct bbd_specific *)dp;
    union tree *tp;
    struct bbd_img *bi;
    struct imgdist id[MAX_IMAGES];
    size_t i;

    /* check the validity of the arguments we got */
    RT_AP_CHECK(ap);
    RT_CHECK_PT(pp);
    CK_bbd_SP(bbd_sp);

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print("bbd_render Parameters:",
			bbd_print_tab, (char *)bbd_sp);
	bu_log("pixel %d %d\n", ap->a_x, ap->a_y);
	bu_log("bbd region: %s\n", pp->pt_regionp->reg_name);
    }
    tp = pp->pt_regionp->reg_treetop;
    if (tp->tr_a.tu_op != OP_SOLID) {
	bu_log("%s:%d region %s rendering bbd should have found OP_SOLID, not %d\n",
	       __FILE__, __LINE__, pp->pt_regionp->reg_name, tp->tr_a.tu_op);
	bu_bomb("\n");
    }


    swp->sw_transmit = 1.0;
    VSETALL(swp->sw_color, 0.0);
    VSETALL(swp->sw_basecolor, 1.0);

    i = 0;
    for (BU_LIST_FOR(bi, bbd_img, &bbd_sp->imgs)) {
	/* find out if the ray hits the plane */
	id[i].index = i;
	id[i].bi = bi;
	id[i].status = bn_isect_line3_plane(&id[i].dist,
					    ap->a_ray.r_pt, ap->a_ray.r_dir,
					    bi->img_plane, &ap->a_rt_i->rti_tol);
	i++;
    }

    bu_sort(id, bbd_sp->img_count, sizeof(id[0]), &imgdist_compare, NULL);

    for (i = 0; i < bbd_sp->img_count && swp->sw_transmit > 0.0; i++) {
	if (id[i].status > 0) do_ray_image(ap, pp, swp, bbd_sp, id[i].bi, id[i].dist);
    }
    if (rdebug&RDEBUG_SHADE) {
	bu_log("color %g %g %g\n", V3ARGS(swp->sw_color));
    }
    /* shader must perform transmission/reflection calculations
     *
     * 0 < swp->sw_transmit <= 1 causes transmission computations
     * 0 < swp->sw_reflect <= 1 causes reflection computations
     */
    if (swp->sw_reflect > 0 || swp->sw_transmit > 0) {
	int level = ap->a_level;
	ap->a_level = 0; /* Bogus hack to keep rr_render from giving up */
	(void)rr_render(ap, pp, swp);
	ap->a_level = level;
    }
    if (rdebug&RDEBUG_SHADE) {
	bu_log("color %g %g %g\n", V3ARGS(swp->sw_color));
    }
    return 1;
}
예제 #11
0
파일: sh_fbm.c 프로젝트: cciechad/brlcad
/*
 *	F B M _ P R I N T
 */
HIDDEN void
fbm_print(register struct region *rp, char *dp)
{
    bu_struct_print( rp->reg_name, fbm_parse, (char *)dp );
}
/*
 * This routine is called (at prep time)
 * once for each region which uses this shader.
 * Any shader-specific initialization should be done here.
 */
HIDDEN int
gauss_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip)


/* pointer to reg_udata in *rp */

/* New since 4.4 release */
{
    register struct gauss_specific *gauss_sp;
    struct tree_bark tb;

    /* check the arguments */
    RT_CHECK_RTI(rtip);
    BU_CK_VLS(matparm);
    RT_CK_REGION(rp);


    if (rdebug&RDEBUG_SHADE)
	bu_log("gauss_setup(%s)\n", rp->reg_name);

    if (! rtip->useair)
	bu_bomb("gauss shader used and useair not set\n");


    /* Get memory for the shader parameters and shader-specific data */
    BU_GET(gauss_sp, struct gauss_specific);
    *dpp = gauss_sp;

    /* initialize the default values for the shader */
    memcpy(gauss_sp, &gauss_defaults, sizeof(struct gauss_specific));

    /* parse the user's arguments for this use of the shader. */
    if (bu_struct_parse(matparm, gauss_parse_tab, (char *)gauss_sp, NULL) < 0)
	return -1;

    /* We have to pick up the parameters for the gaussian puff now.
     * They won't be available later.  So what we do is sneak a peak
     * inside the region, make sure the first item in it is an ellipsoid
     * solid, and if it is go steal a peek at its balls ... er ... make
     * that definition/parameters.
     */

    BU_LIST_INIT(&gauss_sp->dbil);
    tb.l = &gauss_sp->dbil;

    tb.dbip = rtip->rti_dbip;
    tb.name = rp->reg_name;
    tb.gs = gauss_sp;

    tree_solids (rp->reg_treetop, &tb, OP_UNION, &rt_uniresource);


    /* XXX If this puppy isn't axis-aligned, we should come up with a
     * matrix to rotate it into alignment.  We're going to have to do
     * computation in the space defined by this ellipsoid.
     */

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print(" Parameters:", gauss_print_tab, (char *)gauss_sp);
	bn_mat_print("m_to_sh", gauss_sp->gauss_m_to_sh);
    }

    return 1;
}
예제 #13
0
파일: sh_plastic.c 프로젝트: kanzure/brlcad
HIDDEN void
phong_print(register struct region *rp, void *dp)
{
    bu_struct_print(rp->reg_name, phong_parse, (char *)dp);
}
예제 #14
0
파일: sh_plastic.c 프로젝트: kanzure/brlcad
/*
 Color pixel based on the energy of a point light source (Eps)
 plus some diffuse illumination (Epd) reflected from the point
 <x, y> :

 E = Epd + Eps (1)

 The energy reflected from diffuse illumination is the product
 of the reflectance coefficient at point P (Rp) and the diffuse
 illumination (Id) :

 Epd = Rp * Id (2)

 The energy reflected from the point light source is calculated
 by the sum of the diffuse reflectance (Rd) and the specular
 reflectance (Rs), multiplied by the intensity of the light
 source (Ips) :

 Eps = (Rd + Rs) * Ips (3)

 The diffuse reflectance is calculated by the product of the
 reflectance coefficient (Rp) and the cosine of the angle of
 incidence (I) :

 Rd = Rp * cos(I)	(4)

 The specular reflectance is calculated by the product of the
 specular reflectance coefficient and (the cosine of the angle (S)
 raised to the nth power) :

 Rs = W(I) * cos(S)**n (5)

 Where,
 I is the angle of incidence.
 S is the angle between the reflected ray and the observer.
 W returns the specular reflection coefficient as a function
 of the angle of incidence.
 n (roughly 1 to 10) represents the shininess of the surface.
 *
 This is the heart of the lighting model which is based on a model
 developed by Bui-Tuong Phong, [see Wm M. Newman and R. F. Sproull,
 "Principles of Interactive Computer Graphics", 	McGraw-Hill, 1979]

 Er = Ra(m)*cos(Ia) + Rd(m)*cos(I1) + W(I1, m)*cos(s)^^n
 where,

 Er	is the energy reflected in the observer's direction.
 Ra	is the diffuse reflectance coefficient at the point
 of intersection due to ambient lighting.
 Ia	is the angle of incidence associated with the ambient
 light source (angle between ray direction (negated) and
 surface normal).
 Rd	is the diffuse reflectance coefficient at the point
 of intersection due to primary lighting.
 I1	is the angle of incidence associated with the primary
 light source (angle between light source direction and
 surface normal).
 m	is the material identification code.
 W	is the specular reflectance coefficient,
 a function of the angle of incidence, range 0.0 to 1.0,
 for the material.
 s	is the angle between the reflected ray and the observer.
 `	n	'Shininess' of the material,  range 1 to 10.
*/
HIDDEN int
phong_render(register struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
{
    struct light_specific *lp;
#ifndef RT_MULTISPECTRAL
    fastf_t *intensity;
    fastf_t dist;
    point_t pt;
    vect_t color;
#endif
    fastf_t *to_light;
    fastf_t cosine;
    fastf_t refl;
    int i;
    vect_t reflected;
    vect_t work;

#ifdef RT_MULTISPECTRAL
    struct bn_tabdata *ms_matcolor = BN_TABDATA_NULL;
#else
    point_t matcolor;		/* Material color */
#endif
    struct phong_specific *ps =
	(struct phong_specific *)dp;

    if (!ps || ps->magic != PL_MAGIC)
	bu_bomb("phong_render: bad magic\n");

    if (pp == NULL)
	bu_bomb("phong_render: bad partition\n");

    if (rdebug&RDEBUG_SHADE)
	bu_struct_print("phong_render", phong_parse, (char *)ps);

    swp->sw_transmit = ps->transmit;
    swp->sw_reflect = ps->reflect;
    swp->sw_refrac_index = ps->refrac_index;
    swp->sw_extinction = ps->extinction;
#if SW_SET_TRANSMIT
    if (swp->sw_phong_set_vector & SW_SET_TRANSMIT) swp->sw_transmit = swp->sw_phong_transmit;
    if (swp->sw_phong_set_vector & SW_SET_REFLECT) swp->sw_reflect = swp->sw_phong_reflect;
    if (swp->sw_phong_set_vector & SW_SET_REFRAC_INDEX) swp->sw_refrac_index = swp->sw_phong_ri;
    if (swp->sw_phong_set_vector & SW_SET_EXTINCTION) swp->sw_extinction = swp->sw_phong_extinction;
#endif /* SW_SET_TRANSMIT */
    if (swp->sw_xmitonly) {
	if (swp->sw_xmitonly > 1)
	    return 1;	/* done -- wanted parameters only */
	if (swp->sw_reflect > 0 || swp->sw_transmit > 0) {
	    if (rdebug&RDEBUG_SHADE)
		bu_log("calling rr_render from phong, sw_xmitonly\n");
	    (void)rr_render(ap, pp, swp);
	}
	return 1;	/* done */
    }


#ifdef RT_MULTISPECTRAL
    ms_matcolor = bn_tabdata_dup(swp->msw_color);
#else
    VMOVE(matcolor, swp->sw_color);
#endif

    /* Photon Mapping */
#ifndef RT_MULTISPECTRAL
    color[0]= swp->sw_color[0];
    color[1]= swp->sw_color[1];
    color[2]= swp->sw_color[2];
#endif

#ifndef RT_MULTISPECTRAL
    if (!PM_Visualize)
#endif
    {
	/* Diffuse reflectance from "Ambient" light source (at eye) */
	if ((cosine = -VDOT(swp->sw_hit.hit_normal, ap->a_ray.r_dir)) > 0.0) {
	    if (cosine > 1.00001) {
		bu_log("cosAmb=1+%g %s surfno=%d (x%d, y%d, lvl%d)\n",
		       cosine-1,
		       pp->pt_inseg->seg_stp->st_dp->d_namep,
		       swp->sw_hit.hit_surfno,
		       ap->a_x, ap->a_y, ap->a_level);
		VPRINT(" normal", swp->sw_hit.hit_normal);
		VPRINT(" r_dir ", ap->a_ray.r_dir);
		cosine = 1;
	    }
#if SW_SET_TRANSMIT
	    if (swp->sw_phong_set_vector & SW_SET_AMBIENT) {
		cosine *= swp->sw_phong_ambient;
	    } else {
		cosine *= AmbientIntensity;
	    }
#else
	    cosine *= AmbientIntensity;
#endif
#ifdef RT_MULTISPECTRAL
	    bn_tabdata_scale(swp->msw_color, ms_matcolor, cosine);
#else
	    VSCALE(swp->sw_color, matcolor, cosine);
#endif
	} else {
#ifdef RT_MULTISPECTRAL
	    bn_tabdata_constval(swp->msw_color, 0.0);
#else
	    VSETALL(swp->sw_color, 0);
#endif
	}

	/* Emission.  0..1 is normal range, -1..0 sucks light out, like OpenGL */
#ifdef RT_MULTISPECTRAL
	{
	    float emission[3];
	    struct bn_tabdata *ms_emission = BN_TABDATA_NULL;
	    VMOVE(emission, ps->emission);
#if SW_SET_TRANSMIT
	    if (swp->sw_phong_set_vector & SW_SET_EMISSION) {
		VSETALL(emission, swp->sw_phong_emission);
	    }
#endif
	    /* XXX Really should get a curve at prep, not expand RGB samples */
	    BN_GET_TABDATA(ms_emission, spectrum);
	    rt_spect_reflectance_rgb(ms_emission, emission);
	    bn_tabdata_add(swp->msw_color, swp->msw_color, ms_emission);
	    bn_tabdata_free(ms_emission);
	}
#else
#if SW_SET_TRANSMIT
	if (swp->sw_phong_set_vector & SW_SET_EMISSION) {
	    vect_t tmp;
	    VSETALL(tmp, swp->sw_phong_emission);
	    VADD2(swp->sw_color, swp->sw_color, tmp);
	} else {
	    VADD2(swp->sw_color, swp->sw_color, ps->emission);
	}
#else
	VADD2(swp->sw_color, swp->sw_color, ps->emission);
#endif /* SW_SET_TRANSMIT */
#endif

	/* With the advent of procedural shaders, the caller can no longer
	 * provide us reliable light visibility information.  The hit point
	 * may have been changed by another shader in a stack.  There is no
	 * way that anyone else can tell us whether lights are visible.
	 */
	light_obs(ap, swp, ps->mfp->mf_inputs);

	/* Consider effects of each light source */
	for (i=ap->a_rt_i->rti_nlights-1; i>=0; i--) {

	    if ((lp = (struct light_specific *)swp->sw_visible[i]) == LIGHT_NULL)
		continue;

	    if (rdebug & RDEBUG_LIGHT) {
		bu_log("phong_render light=%s lightfract=%g\n",
		       lp->lt_name, swp->sw_lightfract[i]);
	    }

	    /* Light is not shadowed -- add this contribution */
#ifndef RT_MULTISPECTRAL
	    intensity = swp->sw_intensity+3*i;
#endif
	    to_light = swp->sw_tolight+3*i;

	    /* Diffuse reflectance from this light source. */
	    if ((cosine=VDOT(swp->sw_hit.hit_normal, to_light)) > 0.0) {
		if (cosine > 1.00001) {
		    bu_log("cosI=1+%g (x%d, y%d, lvl%d)\n", cosine-1,
			   ap->a_x, ap->a_y, ap->a_level);
		    cosine = 1;
		}
		/* Get Obj Hit Point For Attenuation */
#ifndef RT_MULTISPECTRAL
		if (PM_Activated) {
		    VJOIN1(pt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir);
		    dist= sqrt((pt[0]-lp->lt_pos[0])*(pt[0]-lp->lt_pos[0]) + (pt[1]-lp->lt_pos[1])*(pt[1]-lp->lt_pos[1]) + (pt[2]-lp->lt_pos[2])*(pt[2]-lp->lt_pos[2]))/1000.0;
		    dist= (1.0/(0.1 + 1.0*dist + 0.01*dist*dist));
		    refl= dist * ps->wgt_diffuse * cosine * swp->sw_lightfract[i] * lp->lt_intensity;
		    /* bu_log("pt: [%.3f][%.3f, %.3f, %.3f]\n", dist, pt[0], pt[1], pt[2]);*/
		} else
#endif
		{
		    refl= ps->wgt_diffuse * swp->sw_lightfract[i] * cosine * lp->lt_fraction;
		}

#ifdef RT_MULTISPECTRAL
		bn_tabdata_incr_mul3_scale(swp->msw_color,
					   lp->lt_spectrum,
					   swp->msw_intensity[i],
					   ms_matcolor,
					   refl);
#else
		VELMUL3(work, matcolor, lp->lt_color, intensity);
		VJOIN1(swp->sw_color, swp->sw_color, refl, work);
#endif
	    }

	    /* Calculate specular reflectance.
	     * Reflected ray = (2 * cos(i) * Normal) - Incident ray.
	     * Cos(s) = Reflected ray DOT Incident ray.
	     */
	    cosine *= 2;
	    VSCALE(work, swp->sw_hit.hit_normal, cosine);
	    VSUB2(reflected, work, to_light);
	    if ((cosine = -VDOT(reflected, ap->a_ray.r_dir)) > 0) {
		if (cosine > 1.00001) {
		    bu_log("cosS=1+%g (x%d, y%d, lvl%d)\n", cosine-1,
			   ap->a_x, ap->a_y, ap->a_level);
		    cosine = 1;
		}
		refl = ps->wgt_specular * swp->sw_lightfract[i] *
		    lp->lt_fraction *
#ifdef PHAST_PHONG
		    /* It is unnecessary to compute the actual
		     * exponential here since phong is just a
		     * gross hack.  We approximate re:
		     * Graphics Gems IV "A Fast Alternative to
		     * Phong's Specular Model" Pg 385
		     */
		    cosine /
		    (ps->shine - ps->shine*cosine + cosine);
#else
		phg_ipow(cosine, ps->shine);
#endif /* PHAST_PHONG */
#ifdef RT_MULTISPECTRAL
		bn_tabdata_incr_mul2_scale(swp->msw_color,
					   lp->lt_spectrum,
					   swp->msw_intensity[i],
					   refl);
#else
		VELMUL(work, lp->lt_color, intensity);
		VJOIN1(swp->sw_color, swp->sw_color, refl, work);
#endif
	    }
	}

#ifndef RT_MULTISPECTRAL
	if (PM_Activated) {
	    IrradianceEstimate(ap, work, swp->sw_hit.hit_point, swp->sw_hit.hit_normal);
	    VELMUL(work, work, color);
	    VADD2(swp->sw_color, work, swp->sw_color);
	    if (swp->sw_color[0] > 1.0) swp->sw_color[0]= 1.0;
	    if (swp->sw_color[1] > 1.0) swp->sw_color[1]= 1.0;
	    if (swp->sw_color[2] > 1.0) swp->sw_color[2]= 1.0;
	}

    } else {

	if (PM_Activated) {
	    /* IrradianceEstimate(work, swp->sw_hit.hit_point, swp->sw_hit.hit_normal);
	       VELMUL(swp->sw_color, work, color);*/
	    IrradianceEstimate(ap, swp->sw_color, swp->sw_hit.hit_point, swp->sw_hit.hit_normal);
	    if (swp->sw_color[0] > 1.0) swp->sw_color[0]= 1.0;
	    if (swp->sw_color[1] > 1.0) swp->sw_color[1]= 1.0;
	    if (swp->sw_color[2] > 1.0) swp->sw_color[2]= 1.0;
	}
#endif
    }


    if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	(void)rr_render(ap, pp, swp);

#ifdef RT_MULTISPECTRAL
    bn_tabdata_free(ms_matcolor);
#endif
    return 1;
}
HIDDEN void osl_print(register struct region *rp, void *dp)
{
    bu_struct_print(rp->reg_name, osl_print_tab, (char *)dp);
}
예제 #16
0
파일: sh_scloud.c 프로젝트: kanzure/brlcad
HIDDEN void
scloud_print(register struct region *rp, void *dp)
{
    (void)bu_struct_print(rp->reg_name, scloud_pr, (char *)dp);
}
예제 #17
0
파일: sh_fire.c 프로젝트: cciechad/brlcad
/*
 *	F I R E _ P R I N T
 */
HIDDEN void
fire_print(register struct region *rp, char *dp)
{
    bu_struct_print( rp->reg_name, fire_print_tab, (char *)dp );
}
예제 #18
0
파일: sh_text.c 프로젝트: cciechad/brlcad
/*
 *			T X T _ P R I N T
 */
HIDDEN void
txt_print(register struct region *rp)
{
    bu_struct_print(rp->reg_name, txt_parse, (char *)rp->reg_udata);
}
예제 #19
0
파일: sh_flat.c 프로젝트: kanzure/brlcad
HIDDEN void
flat_print(register struct region *rp, void *dp)
{
    bu_struct_print(rp->reg_name, flat_parse_tab, (char *)dp);
}
예제 #20
0
파일: sh_fire.c 프로젝트: cciechad/brlcad
/*	F I R E _ S E T U P
 *
 *	This routine is called (at prep time)
 *	once for each region which uses this shader.
 *	Any shader-specific initialization should be done here.
 */
HIDDEN int
fire_setup(register struct region *rp, struct bu_vls *matparm, char **dpp, struct mfuncs *mfp, struct rt_i *rtip)


    /* pointer to reg_udata in *rp */

    /* New since 4.4 release */
{
    register struct fire_specific	*fire_sp;

    /* check the arguments */
    RT_CHECK_RTI(rtip);
    BU_CK_VLS( matparm );
    RT_CK_REGION(rp);


    if (rdebug&RDEBUG_SHADE)
	bu_log("fire_setup(%s)\n", rp->reg_name);

    /* Get memory for the shader parameters and shader-specific data */
    BU_GETSTRUCT( fire_sp, fire_specific );
    *dpp = (char *)fire_sp;

    /* initialize the default values for the shader */
    memcpy(fire_sp, &fire_defaults, sizeof(struct fire_specific));

    /* parse the user's arguments for this use of the shader. */
    if (bu_struct_parse( matparm, fire_parse_tab, (char *)fire_sp ) < 0 )
	return(-1);

    if (fire_sp->noise_size != -1.0) {
	VSETALL(fire_sp->noise_vscale, fire_sp->noise_size);
    }

    /*
     * The shader needs to operate in a coordinate system which stays
     * fixed on the region when the region is moved (as in animation).
     * We need to get a matrix to perform the appropriate transform(s).
     */

    db_shader_mat(fire_sp->fire_m_to_sh, rtip, rp, fire_sp->fire_min,
		  fire_sp->fire_max, &rt_uniresource);

    /* Build matrix to map shader space to noise space.
     * XXX If only we could get the frametime at this point
     * we could factor the flicker of flames into this matrix
     * rather than having to recompute it on a pixel-by-pixel basis.
     */
    MAT_IDN(fire_sp->fire_sh_to_noise);
    MAT_DELTAS_VEC(fire_sp->fire_sh_to_noise, fire_sp->noise_delta);
    MAT_SCALE_VEC(fire_sp->fire_sh_to_noise, fire_sp->noise_vscale);

    /* get matrix for performing spline of fire colors */
    rt_dspline_matrix(fire_sp->fire_colorspline_mat, "Catmull", 0.5, 0.0);


    if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug ) {
	bu_struct_print( " FIRE Parameters:", fire_print_tab, (char *)fire_sp );
	bn_mat_print( "m_to_sh", fire_sp->fire_m_to_sh );
	bn_mat_print( "sh_to_noise", fire_sp->fire_sh_to_noise );
	bn_mat_print( "colorspline", fire_sp->fire_colorspline_mat );
    }

    return(1);
}
/*
 * This routine is called (at prep time)
 * once for each region which uses this shader.
 * Any shader-specific initialization should be done here.
 *
 * Returns:
 * 1 success
 * 0 success, but delete region
 * -1 failure
 */
HIDDEN int
bbd_setup(struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
{
    register struct bbd_specific *bbd_sp;
    struct rt_db_internal intern;
    struct rt_tgc_internal *tgc;
    int s;
    mat_t mat;
    struct bbd_img *bi;
    double angle;
    vect_t vtmp;
    int img_num;
    vect_t vv;

    /* check the arguments */
    RT_CHECK_RTI(rtip);
    BU_CK_VLS(matparm);
    RT_CK_REGION(rp);


    if (rdebug&RDEBUG_SHADE) bu_log("bbd_setup(%s)\n", rp->reg_name);

    RT_CK_TREE(rp->reg_treetop);

    if (rp->reg_treetop->tr_a.tu_op != OP_SOLID) {
	bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name);
	bu_bomb("Shader should be used on region of single (rec/rcc) primitive\n");
    }

    RT_CK_SOLTAB(rp->reg_treetop->tr_a.tu_stp);
    if (rp->reg_treetop->tr_a.tu_stp->st_id != ID_REC) {
	bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name);
	bu_log("Shader should be used on region of single REC/RCC primitive %d\n",
	       rp->reg_treetop->tr_a.tu_stp->st_id);
	bu_bomb("oops\n");
    }


    /* Get memory for the shader parameters and shader-specific data */
    BU_GET(bbd_sp, struct bbd_specific);
    *dpp = bbd_sp;

    /* initialize the default values for the shader */
    memcpy(bbd_sp, &bbd_defaults, sizeof(struct bbd_specific));
    bu_vls_init(&bbd_sp->img_filename);
    BU_LIST_INIT(&bbd_sp->imgs);
    bbd_sp->rtip = rtip; /* because new_image() needs this */
    bbd_sp->img_count = 0;

    /* parse the user's arguments for this use of the shader. */
    if (bu_struct_parse(matparm, bbd_parse_tab, (char *)bbd_sp, NULL) < 0)
	return -1;

    if (bbd_sp->img_count > MAX_IMAGES) {
	bu_log("too many images (%zu) in shader for %s sb < %d\n",
	       bbd_sp->img_count, rp->reg_name, MAX_IMAGES);
	bu_bomb("excessive image count\n");
    }


    MAT_IDN(mat);
    RT_DB_INTERNAL_INIT(&intern);
    s = rt_db_get_internal(&intern, rp->reg_treetop->tr_a.tu_stp->st_dp, rtip->rti_dbip,
			   mat, &rt_uniresource);

    if (intern.idb_minor_type != ID_TGC &&
	intern.idb_minor_type != ID_REC) {
	bu_log("What did I get? %d\n", intern.idb_minor_type);
    }

    if (s < 0) {
	bu_log("%s:%d didn't get internal", __FILE__, __LINE__);
	bu_bomb("");
    }
    tgc = (struct rt_tgc_internal *)intern.idb_ptr;
    RT_TGC_CK_MAGIC(tgc);

    angle = M_PI / (double)bbd_sp->img_count;
    img_num = 0;
    VMOVE(vv, tgc->h);
    VUNITIZE(vv);
    for (BU_LIST_FOR(bi, bbd_img, &bbd_sp->imgs)) {
	static const point_t o = VINIT_ZERO;
	bn_mat_arb_rot(mat, o, vv, angle*img_num);

	/* compute plane equation */
	MAT4X3VEC(bi->img_plane, mat, tgc->a);
	VUNITIZE(bi->img_plane);
	bi->img_plane[H] = VDOT(tgc->v, bi->img_plane);

	MAT4X3VEC(vtmp, mat, tgc->b);
	VADD2(bi->img_origin, tgc->v, vtmp); /* image origin in 3d space */
	/* calculate image u vector */
	VREVERSE(bi->img_x, vtmp);
	VUNITIZE(bi->img_x);
	bi->img_xlen = MAGNITUDE(vtmp) * 2;

	/* calculate image v vector */
	VMOVE(bi->img_y, tgc->h);
	VUNITIZE(bi->img_y);
	bi->img_ylen = MAGNITUDE(tgc->h);

	if (rdebug&RDEBUG_SHADE) {
	    HPRINT("\nimg_plane", bi->img_plane);
	    VPRINT("vtmp", vtmp);
	    VPRINT("img_origin", bi->img_origin);
	    bu_log("img_xlen:%g  ", bi->img_xlen);
	    VPRINT("img_x", bi->img_x);
	    bu_log("img_ylen:%g  ", bi->img_ylen);
	    VPRINT("img_y", bi->img_y);
	}

	img_num++;
    }

    rt_db_free_internal(&intern);

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print(" Parameters:", bbd_print_tab, (char *)bbd_sp);
    }

    return 1;
}
/*
 * This is called (from viewshade() in shade.c) once for each hit point
 * to be shaded.  The purpose here is to fill in values in the shadework
 * structure.
 */
int
gauss_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)


/* defined in material.h */
/* ptr to the shader-specific struct */
{
    register struct gauss_specific *gauss_sp =
	(struct gauss_specific *)dp;
    struct seg *seg_p;
    struct reg_db_internals *dbint_p;
    double optical_density = 0.0;

    /* check the validity of the arguments we got */
    RT_AP_CHECK(ap);
    RT_CHECK_PT(pp);
    CK_gauss_SP(gauss_sp);

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print("gauss_render Parameters:", gauss_print_tab, (char *)gauss_sp);

	bu_log("r_pt(%g %g %g) r_dir(%g %g %g)\n",
	       V3ARGS(ap->a_ray.r_pt),
	       V3ARGS(ap->a_ray.r_dir));
    }

    BU_CK_LIST_HEAD(&swp->sw_segs->l);
    BU_CK_LIST_HEAD(&gauss_sp->dbil);


    /* look at each segment that participated in the ray partition(s) */
    for (BU_LIST_FOR(seg_p, seg, &swp->sw_segs->l)) {

	if (rdebug&RDEBUG_SHADE) {
	    bu_log("seg %g -> %g\n",
		   seg_p->seg_in.hit_dist,
		   seg_p->seg_out.hit_dist);
	}
	RT_CK_SEG(seg_p);
	RT_CK_SOLTAB(seg_p->seg_stp);

	/* check to see if the seg/solid is in this partition */
	if (bu_ptbl_locate(&pp->pt_seglist, (long *)seg_p) != -1) {

	    /* XXX You might use a bu_ptbl list of the solid pointers... */
	    /* check to see if the solid is from this region */
	    for (BU_LIST_FOR(dbint_p, reg_db_internals,
			     &gauss_sp->dbil)) {

		CK_DBINT(dbint_p);

		if (dbint_p->st_p == seg_p->seg_stp) {
		    /* The solid from the region is
		     * the solid from the segment
		     * from the partition
		     */
		    optical_density +=
			eval_seg(ap, dbint_p, seg_p);
		    break;
		}
	    }
	} else {
	    if (rdebug&RDEBUG_SHADE)
		bu_log("gauss_render() bittest failed\n");
	}
    }
/*
 * This is called (from viewshade() in shade.c) once for each hit point
 * to be shaded.  The purpose here is to fill in values in the shadework
 * structure.
 */
HIDDEN int osl_render(struct application *ap, const struct partition *pp,
		      struct shadework *swp, void *dp)
/* defined in ../h/shadework.h */
/* ptr to the shader-specific struct */
{
    register struct osl_specific *osl_sp =
	(struct osl_specific *)dp;

    void * thread_info;

    int nsamples; /* Number of samples */

    /* check the validity of the arguments we got */
    RT_AP_CHECK(ap);
    RT_CHECK_PT(pp);
    CK_OSL_SP(osl_sp);

    if (rdebug&RDEBUG_SHADE)
	bu_struct_print("osl_render Parameters:", osl_print_tab,
			(char *)osl_sp);

    bu_semaphore_acquire(BU_SEM_SYSCALL);

    /* Check if it is the first time this thread is calling this function */
    bool visited = false;
    for (size_t i = 0; i < visited_addrs.size(); i++) {
	if (ap->a_resource == visited_addrs[i]) {
	    visited = true;
	    thread_info = thread_infos[i];
	    break;
	}
    }
    if (!visited) {
	visited_addrs.push_back(ap->a_resource);
	/* Get thread specific information from OSLRender system */
	thread_info = oslr->CreateThreadInfo();
	thread_infos.push_back(thread_info);
    }

    if (ap->a_level == 0) {
	default_a_hit = ap->a_hit; /* save the default hit callback (colorview @ rt) */
	default_a_miss = ap->a_miss;
    }
    bu_semaphore_release(BU_SEM_SYSCALL);

    Color3 acc_color(0.0f);

    /* -----------------------------------
     * Fill in all necessary information for the OSL renderer
     * -----------------------------------
     */
    RenderInfo info;
    /* Set hit point */
    VMOVE(info.P, swp->sw_hit.hit_point);

    /* Set normal at the point */
    VMOVE(info.N, swp->sw_hit.hit_normal);

    /* Set incidence ray direction */
    VMOVE(info.I, ap->a_ray.r_dir);

    /* U-V mapping stuff */
    info.u = swp->sw_uv.uv_u;
    info.v = swp->sw_uv.uv_v;
    VSETALL(info.dPdu, 0.0f);
    VSETALL(info.dPdv, 0.0f);

    /* x and y pixel coordinates */
    info.screen_x = ap->a_x;
    info.screen_y = ap->a_y;

    info.depth = ap->a_level;
    info.surfacearea = 1.0f;

    info.shader_ref = osl_sp->shader_ref;

    /* We assume that the only information that will be written is thread_info,
       so that oslr->QueryColor is thread safe */
    info.thread_info = thread_info;


// Ray-tracing (local illumination)

    /* We only perform reflection if application decides to */
    info.doreflection = 0;
    info.out_ray_type = 0;

    Color3 weight = oslr->QueryColor(&info);

    /* Fire another ray */
    if ((info.out_ray_type & RAY_REFLECT) || (info.out_ray_type & RAY_TRANSMIT)) {

	struct application new_ap;
	RT_APPLICATION_INIT(&new_ap);

	new_ap = *ap;                     /* struct copy */
	new_ap.a_onehit = 1;
	new_ap.a_hit = default_a_hit;
	new_ap.a_level = info.depth + 1;
	new_ap.a_flag = 0;

	VMOVE(new_ap.a_ray.r_dir, info.out_ray.dir);
	VMOVE(new_ap.a_ray.r_pt, info.out_ray.origin);

	/* This next ray represents refraction */
	if (info.out_ray_type & RAY_TRANSMIT) {

	    /* Displace the hit point a little bit in the direction
	       of the next ray */
	    Vec3 tmp;
	    VSCALE(tmp, info.out_ray.dir, 1e-4);
	    VADD2(new_ap.a_ray.r_pt, new_ap.a_ray.r_pt, tmp);

	    new_ap.a_onehit = 1;
	    new_ap.a_refrac_index = 1.5;
	    new_ap.a_flag = 2; /* mark as refraction */
	    new_ap.a_hit = osl_refraction_hit;
	}

	(void)rt_shootray(&new_ap);

	Color3 rec;
	VMOVE(rec, new_ap.a_color);

	Color3 res = rec*weight;

	VMOVE(swp->sw_color, res);
    }
    else {
	/* Final color */
	VMOVE(swp->sw_color, weight);
    }

    return 1;
}
HIDDEN void
bbd_print(struct region *rp, void *dp)
{
    bu_struct_print(rp->reg_name, bbd_print_tab, (char *)dp);
}
예제 #25
0
파일: sh_scloud.c 프로젝트: kanzure/brlcad
HIDDEN int
scloud_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)


/* pointer to reg_udata in *rp */


{
    register struct scloud_specific *scloud;
    struct db_full_path full_path;
    mat_t region_to_model;
    mat_t model_to_region;
    mat_t tmp;

    BU_CK_VLS(matparm);
    BU_GET(scloud, struct scloud_specific);
    *dpp = scloud;

    if (rp->reg_aircode == 0) {
        bu_log("WARNING(%s): air shader '%s' applied to non-air region.\n%s\n",
               rp->reg_name,
               mfp->mf_name,
               " Set air flag with \"edcodes\" in mged");
        bu_bomb("");
    }

    memcpy(scloud, &scloud_defaults, sizeof(struct scloud_specific));
    if (rdebug&RDEBUG_SHADE)
        bu_log("scloud_setup\n");

    if (bu_struct_parse(matparm, scloud_parse, (char *)scloud) < 0)
        return -1;

    if (rdebug&RDEBUG_SHADE)
        (void)bu_struct_print(rp->reg_name, scloud_parse, (char *)scloud);

    /* get transformation between world and "region" coordinates */
    if (db_string_to_path(&full_path, rtip->rti_dbip, rp->reg_name)) {
        /* bad thing */
        bu_bomb("db_string_to_path() error");
    }
    if (! db_path_to_mat(rtip->rti_dbip, &full_path, region_to_model, 0, &rt_uniresource)) {
        /* bad thing */
        bu_bomb("db_path_to_mat() error");
    }

    /* get matrix to map points from model space to "region" space */
    bn_mat_inv(model_to_region, region_to_model);

    /* add the noise-space scaling */
    MAT_IDN(tmp);
    if (!EQUAL(scloud->scale, 1.0)) {
        tmp[0] = tmp[5] = tmp[10] = 1.0 / scloud->scale;
    } else {
        tmp[0] = 1.0 / (scloud->vscale[0]);
        tmp[5] = 1.0 / (scloud->vscale[1]);
        tmp[10] = 1.0 / (scloud->vscale[2]);
    }

    bn_mat_mul(scloud->mtos, tmp, model_to_region);

    /* add the translation within noise space */
    MAT_IDN(tmp);
    tmp[MDX] = scloud->delta[0];
    tmp[MDY] = scloud->delta[1];
    tmp[MDZ] = scloud->delta[2];
    bn_mat_mul2(tmp, scloud->mtos);
    bn_mat_inv(scloud->stom, scloud->mtos);

    return 1;
}
예제 #26
0
파일: sh_text.c 프로젝트: kanzure/brlcad
HIDDEN void
ckr_print(register struct region *rp, void *UNUSED(dp))
{
    bu_struct_print(rp->reg_name, ckr_parse, (const char *)rp->reg_udata);
}
예제 #27
0
파일: sh_brdf.c 프로젝트: cciechad/brlcad
/*
 *			B R D F _ R E N D E R
 *
 Color pixel based on the energy of a point light source (Eps)
 plus some diffuse illumination (Epd) reflected from the point
 <x, y> :

 E = Epd + Eps		(1)

 The energy reflected from diffuse illumination is the product
 of the reflectance coefficient at point P (Rp) and the diffuse
 illumination (Id) :

 Epd = Rp * Id		(2)

 The energy reflected from the point light source is calculated
 by the sum of the diffuse reflectance (Rd) and the specular
 reflectance (Rs), multiplied by the intensity of the light
 source (Ips) :

 Eps = (Rd + Rs) * Ips	(3)

 The diffuse reflectance is calculated by the product of the
 reflectance coefficient (Rp) and the cosine of the angle of
 incidence (I) and normalized by PI :

 Rd = Rp * cos(I) / PI	(4)

 The specular reflectance is calculated by the product of the
 specular reflectance coeffient and a term dependent on the
 surface roughness :

 Rs = W(I, O) * R(I, O, r)	(5)

 Where,
 I is the angle of incidence.
 O is the angle to the observer.
 r is the standard deviation (RMS) of the surface slope.
 W returns the specular reflection coefficient as a function
 of the angle of incidence, and the viewer angle.
 R is a surface roughness term.

*/
HIDDEN int
brdf_render(register struct application *ap, struct partition *pp, struct shadework *swp, char *dp)
{
    register struct light_specific *lp;
    register fastf_t *intensity, *to_light;
    register int	i;
    register fastf_t cosi, cosr;
    register fastf_t refl;
    vect_t h_dir;
    vect_t to_eye;
    vect_t	work;
    vect_t	cprod;			/* color product */
    point_t	matcolor;		/* Material color */
    struct brdf_specific *ps =
	(struct brdf_specific *)dp;

    if (ps->magic != BRDF_MAGIC )  bu_log("brdf_render: bad magic\n");

    if (rdebug&RDEBUG_SHADE)
	bu_struct_print( "brdf_render", brdf_parse, (char *)ps );

    swp->sw_transmit = ps->transmit;
    swp->sw_reflect = ps->reflect;
    swp->sw_refrac_index = ps->refrac_index;
    swp->sw_extinction = ps->extinction;
    if (swp->sw_xmitonly ) {
	if (swp->sw_reflect > 0 || swp->sw_transmit > 0 )
	    (void)rr_render( ap, pp, swp );
	return(1);	/* done */
    }

    VMOVE( matcolor, swp->sw_color );

    /* Diffuse reflectance from "Ambient" light source (at eye) */
    if ((cosr = -VDOT( swp->sw_hit.hit_normal, ap->a_ray.r_dir )) > 0.0 )  {
	if (cosr > 1.00001 )  {
	    bu_log("cosAmb=1+%g (x%d, y%d, lvl%d)\n", cosr-1,
		   ap->a_x, ap->a_y, ap->a_level);
	    cosr = 1;
	}
	refl = cosr * AmbientIntensity;
	VSCALE( swp->sw_color, matcolor, refl );
    } else {
	VSETALL( swp->sw_color, 0 );
    }

    VREVERSE( to_eye, ap->a_ray.r_dir );

    /* Consider effects of each light source */
    for ( i=ap->a_rt_i->rti_nlights-1; i>=0; i-- )  {
	fastf_t cos_tmp;
	fastf_t tan_sq;
	double exponent;

	if ((lp = (struct light_specific *)swp->sw_visible[i]) == LIGHT_NULL )
	    continue;

	/* Light is not shadowed -- add this contribution */
	intensity = swp->sw_intensity+3*i;
	to_light = swp->sw_tolight+3*i;

	if ((cosi = VDOT( swp->sw_hit.hit_normal, to_light )) > 0.0 )  {
	    if (cosi > 1.00001 )  {
		bu_log("cosI=1+%g (x%d, y%d, lvl%d)\n", cosi-1,
		       ap->a_x, ap->a_y, ap->a_level);
		cosi = 1;
	    }

	    /* Diffuse reflectance from this light source. */
	    refl = cosi * lp->lt_fraction * ps->diffuse_refl;
	    VELMUL( work, lp->lt_color,
		    intensity );
	    VELMUL( cprod, matcolor, work );
	    VJOIN1( swp->sw_color, swp->sw_color,
		    refl, cprod );

	    /* Calculate specular reflectance. */
	    if (NEAR_ZERO( ps->rms_sq, SMALL_FASTF ) )
		continue;
	    VADD2( h_dir, to_eye, to_light )
		VUNITIZE( h_dir );
	    cos_tmp = VDOT( h_dir, swp->sw_hit.hit_normal );
	    if (cos_tmp <= 0.0 )
		continue;
	    cos_tmp *= cos_tmp;
	    if (NEAR_ZERO( cos_tmp, SMALL_FASTF ) )
		continue;

	    tan_sq = (1.0-cos_tmp)/cos_tmp;
	    exponent = (-tan_sq/ps->rms_sq );
	    refl = ps->specular_refl * lp->lt_fraction * exp( exponent ) /
		sqrt( cosi * cosr ) / ps->denom;
	    if (refl > 1.0 )
		refl = 1.0;

	    VELMUL( work, lp->lt_color, intensity );
	    VJOIN1( swp->sw_color, swp->sw_color, refl, work );

	}
    }

    if (swp->sw_reflect > 0 || swp->sw_transmit > 0 )
	(void)rr_render( ap, pp, swp );
    return(1);
}