home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / devel5 / cursors.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-08  |  7.2 KB  |  323 lines

  1. /* 2D and 3D cursor handling  */
  2. /* some manipulation routines */
  3.  
  4. /* Written by Dave Stampe, Aug. 1992 */
  5.  
  6. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  7.    May be freely used to write software for release into the public domain;
  8.    all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  9.    for permission to incorporate any part of this software into their
  10.    products!
  11.  
  12.      ATTRIBUTION:  If you use any part of this source code or the libraries
  13.      in your projects, you must give attribution to REND386, Dave Stampe,
  14.      and Bernie Roehl in your documentation, source code, and at startup
  15.      of your program.  Let's keep the freeware ball rolling!
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include <dos.h>
  20.  
  21. #include "rend386.h"
  22. #include "f3dkitd.h"
  23. #include "intmath.h"
  24. #include "pointer.h"
  25. #include "cursor.h"
  26. #include "segio.h"
  27. #include "plg.h"
  28. #include "userint.h"
  29.  
  30. extern int manip_2D_avail;
  31. extern int redraw;
  32.  
  33. /***************** 2D (screen) cursor handling ************/
  34.  
  35. static int oldx = 160, oldy = 100;
  36. static int cursor_flag = -1;
  37. static int lastpage;
  38. extern highest_color;
  39.  
  40. void cursor_move(int x, int y) /* move cursor if visible */
  41. {
  42.     oldx = x;
  43.     oldy = y;
  44.     if (cursor_flag == 0)
  45.     {
  46.         set_drawpage(lastpage);
  47.         erase_cursor(lastpage);
  48.         draw_cursor(x,y,-highest_color,lastpage);
  49.     }
  50. }
  51.  
  52. int cursor_hide() /* erase cursor */
  53. {
  54.     if (cursor_flag >= 0) erase_cursor(lastpage);
  55.     --cursor_flag;
  56.     return lastpage;
  57. }
  58.  
  59. int cursor_forget() /* will be erased by redraw: ignore it! */
  60. {
  61.     --cursor_flag;
  62.     return lastpage;
  63. }
  64.  
  65. void cursor_show(int page) /* redisplay cursor */
  66. {
  67.     if (++cursor_flag == 0)
  68.     {
  69.         set_drawpage(page);
  70.         lastpage = page;
  71.         draw_cursor(oldx, oldy, -highest_color, page);
  72.     }
  73. }
  74.  
  75.  
  76. int move_2D(PDRIVER *d, int *x, int *y, unsigned *b)
  77. {
  78.     int c;
  79.  
  80.     if (d == NULL) return 0;
  81.     if (PNEW_POS & (c = mouse_read(d, x, y, b)))
  82.         cursor_move(*x, *y);
  83.     return c;
  84. }
  85.  
  86.  
  87. int move_till_click(PDRIVER *d, unsigned b, int *x, int *y) /* b is button mask */
  88. {
  89.     int s;
  90.     unsigned c;
  91.  
  92.     if (d == NULL) return -1;
  93.     while(1)
  94.     {
  95.         if (((s = move_2D(d, x, y, &c)) & PNEW_BUT) && (c & b)) break;
  96.     }
  97.     return s;
  98. }
  99.  
  100.  
  101. int can_point_2D()
  102. {
  103.     if (!manip_2D_avail)
  104.     {
  105.         popmsg("Mouse not available");
  106.         tdelay(500);
  107.         redraw = 1;
  108.         return 0;
  109.     }
  110.     return 1;
  111. }
  112.  
  113.  
  114. int move_and_select_2D(PDRIVER *d)
  115. {
  116.     int x, y, c;
  117.     unsigned b;
  118.  
  119.     if (!(c = move_2D(d, &x, &y, &b))) return 0; /* no changes */
  120.  
  121.     b &= 1; /* only left button wanted */
  122.  
  123.     if (check_controls(x, y, b)) return 0;
  124.     if(b==1 && y==0) return -1; /* menu callup */
  125.  
  126.     if (b != 0 && (c & PNEW_BUT)) /* new button: DOWN event */
  127.     {
  128.         OBJECT *obj;
  129.  
  130.         obj = where_screen_pt(NULL, NULL, x, y);
  131.         if (obj)
  132.         {
  133.             set_obj_flags(obj, get_obj_flags(obj) ^ OBJ_HIGHLIGHTED);
  134.             if (get_obj_flags(obj) & OBJ_HIGHLIGHTED)
  135.                 highlight_obj(obj);
  136.             else
  137.                 unhighlight_obj(obj);
  138.             redraw = 1;
  139.         }
  140.         else
  141.             {
  142.             popmsg("Not on any object");
  143.             tdelay(300);
  144.         }
  145.         redraw = 1;
  146.     }
  147.     return 0;
  148. }
  149.  
  150.  
  151. /* find world coordinates of pointer based on given view */
  152.  
  153. void pointer_to_world(POINTER *p, VIEW *v, long *x, long *y, long *z)
  154. {
  155.     MATRIX n;
  156.     *x = p->x;
  157.     *y = p->y;
  158.     *z = p->z;
  159.     view_to_matrix(v,n);
  160.     matrix_point(n,x,y,z);
  161.     p->wpos[3][0] = *x;
  162.     p->wpos[3][1] = *y;
  163.     p->wpos[3][2] = *z;
  164.     p->wpos_valid = 1;
  165. }
  166.  
  167.  
  168. /* rotate data to view alignment */
  169.  
  170. void rotate_to_view( VIEW *v, long *x, long *y, long *z)
  171. {
  172.     MATRIX n;
  173.     view_to_matrix(v,n);
  174.     matrix_rotate(n,x,y,z);
  175. }
  176.  
  177.  
  178. /***************** GLOVE CURSOR SUPPORT *************/
  179.  
  180. SEGMENT *wrist_seg = NULL; /* wrist-on-body segment */
  181. /* also used to manip. objects */
  182.  
  183. static SEGMENT *glove_seg; /* wrist twist for presentation */
  184. static SEGMENT *glove_joints[20]; /* joints on hand */
  185.  
  186. #define Y_GLV_OFFSET  0      /* needed as "body" is at neck level */
  187. #define GLOVE_DIST    1000
  188.  
  189. #define SELECT_LENGTH 20    /* distance along last index finger segment */
  190. /* to selection point */
  191.  
  192. int glove_update(PDRIVER *d, POINTER *p) /* read glove, update positions */
  193. {
  194.     int c;
  195.  
  196.     c = pointer_read(d, p);
  197.  
  198.     if ((c & (PNEW_POS | PNEW_ROT | PNEW_FLEX)) == 0) return 0;
  199.  
  200.     abs_move_segment(wrist_seg, p->x, p->y + Y_GLV_OFFSET, p->z + GLOVE_DIST);
  201.     if (d->pdata->type&P_IS6DG)
  202.         abs_rot_segment(wrist_seg, p->rx, p->ry, p->rz, RYXZ);
  203.     else
  204.         abs_rot_segment(glove_seg, -2000L*p->y, p->ry, -4000L*p->x, RYXZ);
  205.  
  206.     abs_rot_segment(glove_joints[1], 0L,30*65536L+18061L*p->flex[0],0L, RYXZ);
  207.     abs_rot_segment(glove_joints[2], -20*65536L,90*65536L,-5*65536L+38700L*p->flex[1], RYZX);
  208.     abs_rot_segment(glove_joints[3], 38700*p->flex[2],0L,0L, RYXZ);
  209.     abs_rot_segment(glove_joints[4], 38700*p->flex[3],0L,0L, RYXZ);
  210.     abs_rot_segment(glove_joints[5], 38700*p->flex[4],0L,0L, RYXZ);
  211.     abs_rot_segment(glove_joints[6], 38700*p->flex[5],0L,0L, RYXZ);
  212.     abs_rot_segment(glove_joints[7], 38700*p->flex[6],0L,0L, RYXZ);
  213.     abs_rot_segment(glove_joints[8], 38700*p->flex[7],0L,0L, RYXZ);
  214.     abs_rot_segment(glove_joints[9], 38700*p->flex[8],0L,0L, RYXZ);
  215.     abs_rot_segment(glove_joints[10],38700*p->flex[9],0L,0L, RYXZ);
  216.  
  217.     redraw = 1;
  218.     return 1;
  219. }
  220.  
  221. extern OBJLIST *objlist; /* only needed during load */
  222. extern void *split_tree;
  223.  
  224. int load_glove_cursor(SEGMENT *body_seg, PDRIVER *gd, char *glove_fname)
  225. {
  226.     int i;
  227.     FILE *in;
  228.     OBJECT *obj;
  229.  
  230.     if ((in = fopen(glove_fname, "r")) == NULL)
  231.         return -1;
  232.     set_readseg_objlist(objlist);
  233.     set_readseg_seglist(glove_joints,20);
  234.     if(!wrist_seg) wrist_seg = new_seg(NULL);
  235.     attach_segment(wrist_seg, body_seg);
  236.  
  237.     if ((gd->pdata->type & P_IS6DG) == 0)
  238.         abs_rot_segment(wrist_seg, 55*65536L, 0, 0, RYXZ); /* glove wrist pose */
  239.  
  240.     readseg_err = 0;
  241.     glove_seg = readseg(in, wrist_seg);
  242.     fclose(in);
  243.  
  244.     if (readseg_err || (glove_seg == NULL))
  245.         return -2;
  246.     for (i = 0; i < 11; i++) /* glove is a non-selectable object */
  247.     {
  248.         void *obj = seg_get_object(glove_joints[i]);
  249.         set_obj_flags(obj, get_obj_flags(obj) | OBJ_NONSEL);
  250.     }
  251.     return 0;
  252. }
  253.  
  254.  
  255. /************* 3D/6D CURSOR SUPPORT ***********/
  256.  
  257. static SEGMENT *cursor_seg;
  258.  
  259. int load_3D_cursor(SEGMENT *body_seg, PDRIVER *gd, char *cursor_fname)
  260. {
  261.     int i;
  262.     FILE *in;
  263.     OBJECT *obj;
  264.  
  265.     if ((in = fopen(cursor_fname, "r")) == NULL)
  266.         return -1;
  267.     cursor_seg = new_seg(body_seg);
  268.     obj = load_plg(in);
  269.     fclose(in);
  270.  
  271.     if (obj)
  272.     {
  273.         seg_set_object(cursor_seg, obj);
  274.         set_object_owner(obj, cursor_seg);
  275.         set_obj_flags(obj, get_obj_flags(obj) | OBJ_NONSEL);
  276.         add_obj_to_split_area(split_tree, obj);
  277.         update_segment(cursor_seg);
  278.         return 0;
  279.     }
  280.     else
  281.         return -2;
  282. }
  283.  
  284.  
  285. int cursor_update3D(PDRIVER *d, POINTER *p) /* read pointer, update positions */
  286. {
  287.     int c;
  288.  
  289.     c = pointer_read(d, p);
  290.  
  291.     if ((c & (PNEW_POS | PNEW_ROT)) == 0) return 0;
  292.  
  293.     abs_move_segment(cursor_seg, p->x, p->y + Y_GLV_OFFSET, p->z + GLOVE_DIST);
  294.     abs_rot_segment(cursor_seg, p->rx, p->ry, p->rz, RYXZ);
  295.  
  296.     redraw = 1;
  297.     return 1;
  298. }
  299.  
  300.  
  301.  
  302. /************* USED FOR 3D/6D MANIPULATION *************/
  303.  
  304. extern int have_ptr;
  305.  
  306. SEGMENT *manip_data(PDRIVER *d, long *x, long *y, long *z)
  307. {
  308.  
  309.     if (!have_ptr)
  310.     {
  311.         *x = 0;
  312.         *y = 0;
  313.         *z = SELECT_LENGTH;
  314.         matrix_point(*get_seg_pmatrix(glove_joints[4]), x, y, z);
  315.         return wrist_seg;
  316.     }
  317.     else
  318.         {
  319.         seg_getposxyz(cursor_seg, x ,y ,z);
  320.         return cursor_seg;
  321.     }
  322. }
  323.