PageRenderTime 29ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/brlcad/tags/rel-6-1-DP/liboptical/sh_prj.c

https://bitbucket.org/vrrm/brl-cad-copy-for-fast-history-browsing-in-git
C | 724 lines | 481 code | 125 blank | 118 comment | 62 complexity | 5b643744dabc50225554903a818a75ae MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, Apache-2.0, AGPL-3.0, LGPL-3.0, GPL-3.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, 0BSD, BSD-3-Clause
  1. /*
  2. * S H _ P R J . C
  3. *
  4. * Projection shader
  5. *
  6. * The one parameter to this shader is a filename. The named file
  7. * contains the REAL parameters to the shader. The v4 database format
  8. * is far too anemic to support this sort of shader.
  9. *
  10. */
  11. #include "conf.h"
  12. #include <stdio.h>
  13. #include <fcntl.h>
  14. #include <string.h>
  15. #include <errno.h>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <math.h>
  19. #include "machine.h"
  20. #include "bu.h"
  21. #include "vmath.h"
  22. #include "raytrace.h"
  23. #include "shadefuncs.h"
  24. #include "shadework.h"
  25. #include "../rt/ext.h"
  26. #include "rtprivate.h"
  27. #include "plot3.h"
  28. #define prj_MAGIC 0x70726a00 /* "prj" */
  29. #define CK_prj_SP(_p) BU_CKMAG(_p, prj_MAGIC, "prj_specific")
  30. struct img_specific {
  31. struct bu_list l;
  32. unsigned long junk;
  33. struct bu_vls i_file;
  34. struct bu_mapped_file *i_data;
  35. unsigned char *i_img;
  36. int i_width;
  37. int i_height;
  38. fastf_t i_viewsize;
  39. point_t i_eye_pt;
  40. quat_t i_orient;
  41. mat_t i_mat; /* computed from i_orient */
  42. mat_t i_bn_mat_inv; /* computed (for debug) */
  43. plane_t i_plane; /* dir/plane of projection */
  44. mat_t i_sh_to_img; /* transform used in prj_render() */
  45. char i_through; /* ignore surface normal */
  46. char i_antialias; /* anti-alias texture */
  47. char i_behind; /* shade points behind img plane */
  48. fastf_t i_perspective; /* perspective angle 0=ortho */
  49. };
  50. #define img_MAGIC 0x696d6700 /* "img" */
  51. /*
  52. * the shader specific structure contains all variables which are unique
  53. * to any particular use of the shader.
  54. */
  55. struct prj_specific {
  56. unsigned long magic;
  57. struct img_specific prj_images;
  58. mat_t prj_m_to_sh;
  59. FILE *prj_plfd;
  60. };
  61. /*
  62. *
  63. * Bounds checking on perspective angle
  64. *
  65. */
  66. static void
  67. persp_hook( sdp, name, base, value )
  68. register const struct bu_structparse *sdp; /* structure description */
  69. register const char *name; /* struct member name */
  70. char *base; /* begining of structure */
  71. const char *value; /* string containing value */
  72. {
  73. struct img_specific *img_sp = (struct img_specific *)base;
  74. if (img_sp->i_perspective < 0.0) {
  75. bu_log("perspecitve %s < 0.0\n", value);
  76. bu_bomb("");
  77. }
  78. if (img_sp->i_perspective > 180.0) {
  79. bu_log("perspective %s > 180.\n", value);
  80. bu_bomb("");
  81. }
  82. if (img_sp->i_perspective != 0.0)
  83. bu_bomb("non-ortho perspective not yet implemented!\n");
  84. }
  85. /*
  86. * Check for value < 0.0
  87. *
  88. */
  89. static void
  90. dimen_hook( sdp, name, base, value )
  91. register const struct bu_structparse *sdp; /* structure description */
  92. register const char *name; /* struct member name */
  93. char *base; /* begining of structure */
  94. const char *value; /* string containing value */
  95. {
  96. if (! strcmp("%f", sdp->sp_fmt)) {
  97. fastf_t *f;
  98. f = (fastf_t *)(base + sdp->sp_offset);
  99. if (*f < 0.0) {
  100. bu_log("%s value %g(%s) < 0.0\n",
  101. sdp->sp_name, *f, value);
  102. bu_bomb("");
  103. }
  104. } else if (! strcmp("%d", sdp->sp_fmt)) {
  105. int *i;
  106. i = (int *)(base + sdp->sp_offset);
  107. if (*i < 0) {
  108. bu_log("%s value %d(%s) < 0.0\n",
  109. sdp->sp_name, *i, value);
  110. bu_bomb("");
  111. }
  112. }
  113. }
  114. #if 0
  115. static void
  116. noop_hook( sdp, name, base, value )
  117. register const struct bu_structparse *sdp; /* structure description */
  118. register const char *name; /* struct member name */
  119. char *base; /* begining of structure */
  120. const char *value; /* string containing value */
  121. {
  122. struct img_specific *img_sp = (struct img_specific *)base;
  123. BU_CK_LIST_HEAD(&img_sp->l);
  124. bu_log("%s \"%s\"\n", sdp->sp_name, value);
  125. BU_CK_VLS(&img_sp->i_file);
  126. }
  127. #endif
  128. /*
  129. * This routine is responsible for duplicating the image list head to make
  130. * a new list element. It also reads in the pixel data for the image, and
  131. * computes the matrix from the view quaternion.
  132. *
  133. * XXX "orient" MUST ALWAYS BE THE LAST PARAMETER SPECIFIED FOR EACH IMAGE.
  134. */
  135. static void
  136. orient_hook( sdp, name, base, value )
  137. register const struct bu_structparse *sdp; /* structure description */
  138. register const char *name; /* struct member name */
  139. char *base; /* begining of structure */
  140. const char *value; /* string containing value */
  141. {
  142. struct prj_specific *prj_sp;
  143. struct img_specific *img_sp = (struct img_specific *)base;
  144. struct img_specific *img_new;
  145. mat_t trans, scale, tmp, xform;
  146. vect_t v_tmp;
  147. point_t p_tmp;
  148. BU_CK_LIST_HEAD(&img_sp->l);
  149. /* create a new img_specific struct,
  150. * copy the parameters from the "head" into the new
  151. * img_specific struct
  152. */
  153. BU_GETSTRUCT(img_new, img_specific);
  154. memcpy(img_new, img_sp, sizeof(struct img_specific));
  155. BU_CK_VLS(&img_sp->i_file);
  156. /* zero the filename for the next iteration */
  157. bu_vls_init(&img_sp->i_file);
  158. /* Generate matrix from the quaternion */
  159. quat_quat2mat(img_new->i_mat, img_new->i_orient);
  160. /* compute matrix to transform region coordinates into
  161. * shader projection coordinates:
  162. *
  163. * prj_coord = scale * rot * translate * region_coord
  164. */
  165. MAT_IDN(trans);
  166. MAT_DELTAS_VEC_NEG(trans, img_new->i_eye_pt);
  167. MAT_IDN(scale);
  168. MAT_SCALE_ALL(scale, img_new->i_viewsize);
  169. bn_mat_mul(tmp, img_new->i_mat, trans);
  170. bn_mat_mul(img_new->i_sh_to_img, scale, tmp);
  171. VSET(v_tmp, 0.0, 0.0, 1.0);
  172. /* compute inverse */
  173. bn_mat_inv(img_new->i_bn_mat_inv, img_new->i_mat);
  174. bn_mat_inv(xform, img_new->i_sh_to_img);
  175. MAT4X3VEC(img_new->i_plane, xform, v_tmp);
  176. VUNITIZE(img_new->i_plane);
  177. if (rdebug&RDEBUG_SHADE) {
  178. point_t pt;
  179. #if 0
  180. img_new->i_plane[H] =
  181. VDOT(img_new->i_plane, img_new->i_eye_pt);
  182. #endif
  183. prj_sp = (struct prj_specific *)
  184. (base - (offsetof(struct prj_specific, prj_images)));
  185. CK_prj_SP(prj_sp);
  186. if (!prj_sp->prj_plfd)
  187. bu_bomb("prj shader prj_plfd should be open\n");
  188. /* plot out the extent of the image frame */
  189. pl_color(prj_sp->prj_plfd, 255, 0, 0);
  190. VSET(v_tmp, -0.5, -0.5, 0.0);
  191. MAT4X3PNT(pt, xform, v_tmp);
  192. pdv_3move(prj_sp->prj_plfd, pt);
  193. VSET(v_tmp, 0.5, -0.5, 0.0);
  194. MAT4X3PNT(p_tmp, xform, v_tmp);
  195. pdv_3cont(prj_sp->prj_plfd, p_tmp);
  196. VSET(v_tmp, 0.5, 0.5, 0.0);
  197. MAT4X3PNT(p_tmp, xform, v_tmp);
  198. pdv_3cont(prj_sp->prj_plfd, p_tmp);
  199. VSET(v_tmp, -0.5, 0.5, 0.0);
  200. MAT4X3PNT(p_tmp, xform, v_tmp);
  201. pdv_3cont(prj_sp->prj_plfd, p_tmp);
  202. pdv_3cont(prj_sp->prj_plfd, pt);
  203. VSET(v_tmp, 0.0, 0.0, 0.0);
  204. MAT4X3PNT(p_tmp, xform, v_tmp);
  205. pdv_3move(prj_sp->prj_plfd, p_tmp);
  206. VREVERSE(pt, img_new->i_plane);
  207. VADD2(p_tmp, p_tmp, pt);
  208. pdv_3cont(prj_sp->prj_plfd, p_tmp);
  209. }
  210. /* read in the pixel data */
  211. img_new->i_data = bu_open_mapped_file(bu_vls_addr(&img_new->i_file),
  212. (char *)NULL);
  213. if ( ! img_new->i_data)
  214. bu_bomb("shader prj: orient_hook() can't get pixel data... bombing\n");
  215. img_new->i_img = (unsigned char *)img_new->i_data->buf;
  216. BU_LIST_MAGIC_SET(&img_new->l, img_MAGIC);
  217. BU_LIST_APPEND(&img_sp->l, &img_new->l);
  218. }
  219. #define IMG_O(m) offsetof(struct img_specific, m)
  220. #define IMG_AO(m) bu_offsetofarray(struct img_specific, m)
  221. /* description of how to parse/print the arguments to the shader
  222. * There is at least one line here for each variable in the shader specific
  223. * structure above
  224. */
  225. struct bu_structparse img_parse_tab[] = {
  226. {"%S", 1, "image", IMG_O(i_file), BU_STRUCTPARSE_FUNC_NULL},
  227. {"%d", 1, "w", IMG_O(i_width), dimen_hook},
  228. {"%d", 1, "n", IMG_O(i_height), dimen_hook},
  229. {"%f", 1, "viewsize", IMG_O(i_viewsize), dimen_hook},
  230. {"%f", 3, "eye_pt", IMG_AO(i_eye_pt), BU_STRUCTPARSE_FUNC_NULL},
  231. {"%f", 4, "orientation", IMG_AO(i_orient), orient_hook},
  232. {"%c", 1, "through", IMG_O(i_through), BU_STRUCTPARSE_FUNC_NULL},
  233. {"%c", 1, "antialias", IMG_O(i_antialias), BU_STRUCTPARSE_FUNC_NULL},
  234. {"%c", 1, "behind", IMG_O(i_behind), BU_STRUCTPARSE_FUNC_NULL},
  235. {"%c", 1, "perspective", IMG_O(i_perspective), persp_hook},
  236. {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL}
  237. };
  238. struct bu_structparse img_print_tab[] = {
  239. {"i", bu_byteoffset(img_parse_tab[0]), "img_parse_tab", 0, BU_STRUCTPARSE_FUNC_NULL },
  240. {"%f", 4, "i_plane", IMG_AO(i_plane), BU_STRUCTPARSE_FUNC_NULL},
  241. {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL}
  242. };
  243. HIDDEN int prj_setup(), prj_render();
  244. HIDDEN void prj_print(), prj_free();
  245. /* The "mfuncs" structure defines the external interface to the shader.
  246. * Note that more than one shader "name" can be associated with a given
  247. * shader by defining more than one mfuncs struct in this array.
  248. * See sh_phong.c for an example of building more than one shader "name"
  249. * from a set of source functions. There you will find that "glass" "mirror"
  250. * and "plastic" are all names for the same shader with different default
  251. * values for the parameters.
  252. */
  253. struct mfuncs prj_mfuncs[] = {
  254. {MF_MAGIC, "prj", 0, MFI_NORMAL|MFI_HIT|MFI_UV, 0,
  255. prj_setup, prj_render, prj_print, prj_free },
  256. {0, (char *)0, 0, 0, 0,
  257. 0, 0, 0, 0 }
  258. };
  259. /* P R J _ S E T U P
  260. *
  261. * This routine is called (at prep time)
  262. * once for each region which uses this shader.
  263. * Any shader-specific initialization should be done here.
  264. */
  265. HIDDEN int
  266. prj_setup( rp, matparm, dpp, mfp, rtip)
  267. register struct region *rp;
  268. struct bu_vls *matparm;
  269. char **dpp; /* pointer to reg_udata in *rp */
  270. struct mfuncs *mfp;
  271. struct rt_i *rtip; /* New since 4.4 release */
  272. {
  273. struct prj_specific *prj_sp;
  274. struct img_specific *img_sp;
  275. char *fname;
  276. struct bu_vls parameter_data;
  277. struct bu_mapped_file *parameter_file;
  278. /* check the arguments */
  279. RT_CHECK_RTI(rtip);
  280. BU_CK_VLS( matparm );
  281. RT_CK_REGION(rp);
  282. if (rdebug&RDEBUG_SHADE)
  283. bu_log("prj_setup(%s) matparm:\"%s\"\n",
  284. rp->reg_name, bu_vls_addr(matparm));
  285. /* Get memory for the shader parameters and shader-specific data */
  286. BU_GETSTRUCT( prj_sp, prj_specific );
  287. *dpp = (char *)prj_sp;
  288. prj_sp->magic = prj_MAGIC;
  289. BU_LIST_INIT(&prj_sp->prj_images.l);
  290. if (rdebug&RDEBUG_SHADE) {
  291. if ((prj_sp->prj_plfd=fopen("prj.pl", "w")) == (FILE *)NULL) {
  292. bu_log("ERROR creating plot file prj.pl");
  293. }
  294. } else
  295. prj_sp->prj_plfd = (FILE *)NULL;
  296. fname = bu_vls_addr(matparm);
  297. #if 0
  298. if (! isspace(*fname) )
  299. bu_log("------ Stack shader fixed? Remove hack from prj shader ----\n");
  300. while (isspace(*fname)) fname++; /* XXX Hack till stack shader fixed */
  301. #endif
  302. if (! *fname)
  303. bu_bomb("Null prj shaderfile?\n");
  304. parameter_file = bu_open_mapped_file( fname, (char *)NULL );
  305. if (! parameter_file) {
  306. bu_log( "prj_setup can't get shaderfile (%s)\n", fname );
  307. bu_bomb("prj_setup can't get shaderfile... bombing\n");
  308. }
  309. bu_vls_init(&parameter_data);
  310. bu_vls_strncpy( &parameter_data, (char *)parameter_file->buf,
  311. parameter_file->buflen );
  312. if (rdebug&RDEBUG_SHADE ) {
  313. bu_log("parsing: %s\n", bu_vls_addr(&parameter_data));
  314. }
  315. bu_close_mapped_file( parameter_file );
  316. /* set defaults on img_specific struct */
  317. prj_sp->prj_images.i_width = prj_sp->prj_images.i_height = 512;
  318. prj_sp->prj_images.i_antialias = '1';
  319. prj_sp->prj_images.i_through = '0';
  320. prj_sp->prj_images.i_behind = '0';
  321. if(bu_struct_parse( &parameter_data, img_parse_tab,
  322. (char *)&prj_sp->prj_images) < 0)
  323. return -1;
  324. /* if even one of the images is to be anti-aliased, then we need
  325. * to set the rti_prismtrace flag so that we can compute the exact
  326. * extent of the pixel.
  327. */
  328. for (BU_LIST_FOR(img_sp, img_specific, &prj_sp->prj_images.l)) {
  329. if (img_sp->i_antialias != '0') {
  330. if (rdebug&RDEBUG_SHADE)
  331. bu_log("prj_setup(%s) setting prismtrace 1\n", rp->reg_name);
  332. rtip->rti_prismtrace = 1;
  333. break;
  334. }
  335. }
  336. bu_vls_free( &parameter_data );
  337. /* The shader needs to operate in a coordinate system which stays
  338. * fixed on the region when the region is moved (as in animation)
  339. * we need to get a matrix to perform the appropriate transform(s).
  340. *
  341. * db_region_mat returns a matrix which maps points on/in the region
  342. * as it exists where the region is defined (as opposed to the
  343. * (possibly transformed) one we are rendering.
  344. *
  345. * Non-PARALLEL, which is OK, because shaders are prepped serially.
  346. */
  347. db_region_mat(prj_sp->prj_m_to_sh, rtip->rti_dbip, rp->reg_name, &rt_uniresource);
  348. if (rdebug&RDEBUG_SHADE) {
  349. prj_print(rp, (char *)prj_sp );
  350. }
  351. return(1);
  352. }
  353. /*
  354. * P R J _ P R I N T
  355. */
  356. HIDDEN void
  357. prj_print( rp, dp )
  358. register struct region *rp;
  359. char *dp;
  360. {
  361. struct prj_specific *prj_sp = (struct prj_specific *)dp;
  362. struct img_specific *img_sp;
  363. for (BU_LIST_FOR(img_sp, img_specific, &prj_sp->prj_images.l)) {
  364. bu_struct_print( rp->reg_name, img_print_tab, (char *)img_sp );
  365. }
  366. }
  367. /*
  368. * P R J _ F R E E
  369. */
  370. HIDDEN void
  371. prj_free( cp )
  372. char *cp;
  373. {
  374. struct prj_specific *prj_sp = (struct prj_specific *)cp;
  375. struct img_specific *img_sp;
  376. while (BU_LIST_WHILE(img_sp, img_specific, &prj_sp->prj_images.l)) {
  377. img_sp->i_img = (unsigned char *)0;
  378. bu_close_mapped_file( img_sp->i_data );
  379. bu_vls_vlsfree(&img_sp->i_file);
  380. BU_LIST_DEQUEUE( &img_sp->l );
  381. bu_free( (char *)img_sp, "img_specific");
  382. }
  383. if ( prj_sp->prj_plfd ) {
  384. bu_semaphore_acquire( BU_SEM_SYSCALL );
  385. fclose( prj_sp->prj_plfd );
  386. bu_semaphore_release( BU_SEM_SYSCALL );
  387. }
  388. bu_free( cp, "prj_specific" );
  389. }
  390. static const double cs = (1.0/255.0);
  391. static const point_t delta = {0.5, 0.5, 0.0};
  392. #if 0
  393. static int
  394. project_antialiased(sh_color, img_sp, prj_sp, ap, r_pe, r_N, r_pt)
  395. point_t sh_color;
  396. const struct img_specific *img_sp;
  397. const struct prj_specific *prj_sp;
  398. const struct application *ap;
  399. const struct pixel_ext *r_pe; /* pts on plane of hit */
  400. const plane_t r_N;
  401. const point_t r_pt;
  402. {
  403. int i, x, y;
  404. point_t sh_pts[CORNER_PTS];
  405. struct pixel_ext pe;
  406. /* project hit plane corner points into image space */
  407. for (i=0 ; i < CORNER_PTS ; i++) {
  408. MAT4X3PNT(sh_pts[i], img_sp->i_sh_to_img,
  409. pe.corner[i].r_pt);
  410. /* compute image coordinates */
  411. sh_pts[i][Z] = 0.0;
  412. VADD2(sh_pts[i], sh_pts[i], delta);
  413. sh_pts[i][X] *= img_sp->i_width - 1;
  414. sh_pts[i][Y] *= img_sp->i_height - 1;
  415. x = sh_pts[i][X];
  416. y = sh_pts[i][Y];
  417. sh_pts[i][X] = x;
  418. sh_pts[i][y] = y;
  419. }
  420. return 0;
  421. }
  422. #endif
  423. static int
  424. project_point(sh_color, img_sp, prj_sp, r_pt)
  425. point_t sh_color;
  426. struct img_specific *img_sp;
  427. struct prj_specific *prj_sp;
  428. point_t r_pt;
  429. {
  430. int x, y;
  431. point_t sh_pt;
  432. point_t tmp_pt;
  433. unsigned char *pixel;
  434. MAT4X3PNT(sh_pt, img_sp->i_sh_to_img, r_pt);
  435. VADD2(sh_pt, sh_pt, delta);
  436. if (rdebug&RDEBUG_SHADE) {
  437. VPRINT("sh_pt", sh_pt);
  438. }
  439. x = sh_pt[X] * (img_sp->i_width-1);
  440. y = sh_pt[Y] * (img_sp->i_height-1);
  441. pixel = &img_sp->i_img[x*3 + y*img_sp->i_width*3];
  442. if (x >= img_sp->i_width || x < 0 ||
  443. y >= img_sp->i_height || y < 0 ||
  444. ((img_sp->i_behind == '0' && sh_pt[Z] > 0.0)) ) {
  445. /* we're out of bounds,
  446. * leave the color alone
  447. */
  448. return 1;
  449. }
  450. if (rdebug&RDEBUG_SHADE && prj_sp->prj_plfd) {
  451. /* plot projection direction */
  452. pl_color(prj_sp->prj_plfd, V3ARGS(pixel));
  453. pdv_3move(prj_sp->prj_plfd, r_pt);
  454. VMOVE(tmp_pt, r_pt);
  455. VSCALE(tmp_pt, img_sp->i_plane, -sh_pt[Z]);
  456. VADD2(tmp_pt, r_pt, tmp_pt);
  457. pdv_3cont(prj_sp->prj_plfd, tmp_pt);
  458. }
  459. VMOVE(sh_color, pixel); /* int/float conversion */
  460. return 0;
  461. }
  462. /*
  463. * P R J _ R E N D E R
  464. *
  465. * This is called (from viewshade() in shade.c) once for each hit point
  466. * to be shaded. The purpose here is to fill in values in the shadework
  467. * structure.
  468. */
  469. int
  470. prj_render( ap, pp, swp, dp )
  471. struct application *ap;
  472. struct partition *pp;
  473. struct shadework *swp; /* defined in material.h */
  474. char *dp; /* ptr to the shader-specific struct */
  475. {
  476. register struct prj_specific *prj_sp =
  477. (struct prj_specific *)dp;
  478. point_t r_pt;
  479. plane_t r_N;
  480. int i, status;
  481. struct img_specific *img_sp;
  482. point_t sh_color;
  483. point_t final_color;
  484. point_t tmp_pt;
  485. fastf_t divisor;
  486. struct pixel_ext r_pe; /* region coord version of ap->a_pixelext */
  487. fastf_t dist;
  488. fastf_t weight;
  489. /* check the validity of the arguments we got */
  490. RT_AP_CHECK(ap);
  491. RT_CHECK_PT(pp);
  492. CK_prj_SP(prj_sp);
  493. if (rdebug&RDEBUG_SHADE) {
  494. bu_log("shading with prj\n");
  495. prj_print(pp->pt_regionp, dp);
  496. }
  497. /* If we are performing the shading in "region" space, we must
  498. * transform the hit point from "model" space to "region" space.
  499. * See the call to db_region_mat in prj_setup().
  500. */
  501. MAT4X3PNT(r_pt, prj_sp->prj_m_to_sh, swp->sw_hit.hit_point);
  502. MAT4X3VEC(r_N, prj_sp->prj_m_to_sh, swp->sw_hit.hit_normal);
  503. if (rdebug&RDEBUG_SHADE) {
  504. bu_log("prj_render() model:(%g %g %g) shader:(%g %g %g)\n",
  505. V3ARGS(swp->sw_hit.hit_point),
  506. V3ARGS(r_pt) );
  507. }
  508. VSET(final_color, 0.0, 0.0, 0.0);
  509. divisor = 0.0;
  510. if (ap->a_pixelext) {
  511. BU_CK_PIXEL_EXT(ap->a_pixelext);
  512. /* We need to compute the extent of the pixel on an
  513. * imaginary plane through the hit point with the same
  514. * normal as the surface normal at the hit point. Later
  515. * this quadrilateral will be projected onto the image
  516. * plane(s) to facilitate anti-aliasing.
  517. */
  518. /* compute region coordinates for pixel extent */
  519. for ( i=0 ; i < CORNER_PTS ; i++) {
  520. MAT4X3PNT(r_pe.corner[i].r_pt,
  521. prj_sp->prj_m_to_sh,
  522. ap->a_pixelext->corner[i].r_pt);
  523. MAT4X3VEC(r_pe.corner[i].r_dir,
  524. prj_sp->prj_m_to_sh,
  525. ap->a_pixelext->corner[i].r_dir);
  526. }
  527. /* compute plane of hit point */
  528. VUNITIZE(r_N);
  529. r_N[H] = VDOT(r_N, r_pt);
  530. /* project corner points into plane of hit point */
  531. for (i=0 ; i < CORNER_PTS ; i++) {
  532. dist = 0.0;
  533. status = bn_isect_line3_plane(
  534. &dist,
  535. r_pe.corner[i].r_pt,
  536. r_pe.corner[i].r_dir,
  537. r_N,
  538. &(ap->a_rt_i->rti_tol));
  539. if (status <= 0) {
  540. /* XXX What to do if we don't
  541. * hit plane?
  542. */
  543. bu_log("%s:%d The unthinkable has happened\n",
  544. __FILE__, __LINE__);
  545. }
  546. VJOIN1(r_pe.corner[i].r_pt,
  547. r_pe.corner[i].r_pt,
  548. dist,
  549. r_pe.corner[i].r_dir);
  550. }
  551. }
  552. for (BU_LIST_FOR(img_sp, img_specific, &prj_sp->prj_images.l)) {
  553. if ( img_sp->i_through == '0' && VDOT(r_N, img_sp->i_plane) < 0.0) {
  554. /* normal and projection dir don't match, skip on */
  555. if (rdebug&RDEBUG_SHADE && prj_sp->prj_plfd) {
  556. /* plot hit normal */
  557. pl_color(prj_sp->prj_plfd, 255, 255, 255);
  558. pdv_3move(prj_sp->prj_plfd, r_pt);
  559. VADD2(tmp_pt, r_pt, r_N);
  560. pdv_3cont(prj_sp->prj_plfd, tmp_pt);
  561. /* plot projection direction */
  562. pl_color(prj_sp->prj_plfd, 255, 255, 0);
  563. pdv_3move(prj_sp->prj_plfd, r_pt);
  564. VADD2(tmp_pt, r_pt, img_sp->i_plane);
  565. pdv_3cont(prj_sp->prj_plfd, tmp_pt);
  566. }
  567. continue;
  568. }
  569. #if 0
  570. if (img_sp->i_antialias == '1') {
  571. if (ap->a_pixelext)
  572. bu_bomb("pixel corners structure not set\n");
  573. if (project_antialiased(sh_color, img_sp, prj_sp,
  574. ap, &r_pe, r_N, r_pt))
  575. continue;
  576. } else {
  577. if (project_point(sh_color, img_sp, prj_sp, r_pt))
  578. continue;
  579. }
  580. #else
  581. if (project_point(sh_color, img_sp, prj_sp, r_pt))
  582. continue;
  583. #endif
  584. VSCALE(sh_color, sh_color, cs);
  585. weight = VDOT( r_N, img_sp->i_plane );
  586. if (img_sp->i_through != '0' )
  587. weight = (weight < 0.0 ? -weight : weight );
  588. if (weight > 0.0 )
  589. {
  590. VJOIN1(final_color, final_color, weight, sh_color);
  591. divisor += weight;
  592. }
  593. }
  594. if (divisor > 0.0) {
  595. divisor = 1.0 / divisor;
  596. VSCALE(swp->sw_color, final_color, divisor);
  597. }
  598. return 1;
  599. }