home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Zone
/
VRZONE.ISO
/
mac
/
PC
/
PCGLOVE
/
GLOVE
/
OBJGLV.ZIP
/
SRC
/
DEMO4B
/
CURSORS.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-09
|
9KB
|
367 lines
/* 2D and 3D cursor handling */
/* some manipulation routines */
/* Written by Dave Stampe, Aug. 1992 */
/* Copyright 1992 by Bernie Roehl.
May be freely used to write software for release into the public domain;
all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
for permission to incorporate any part of this software into their
products!
*/
#include <stdio.h>
#include <dos.h>
#include "rend386.hpp"
#include "vd2.hpp"
#include "intmath.h"
#include "pointer.hpp"
#include "cursor.hpp"
#include "segio.hpp"
#include "plg.h"
#include "userint.hpp"
#include "world.hpp"
#include "keyboard.hpp"
#include "splits.hpp"
#include "inputptr.hpp"
/***************** 2D (screen) cursor handling ************/
static int oldx = 160, oldy = 100;
static int cursor_flag = -1;
static int lastpage;
void cursor_move(int x, int y) /* move cursor if visible */
{
oldx = x;
oldy = y;
if (cursor_flag == 0)
{
set_drawpage(lastpage);
erase_cursor(lastpage);
draw_cursor(x,y,0,lastpage);
}
}
int cursor_hide() /* erase cursor */
{
if (cursor_flag >= 0) erase_cursor(lastpage);
--cursor_flag;
return lastpage;
}
int cursor_forget() /* will be erased by redraw: ignore it! */
{
--cursor_flag;
return lastpage;
}
void cursor_show(int page) /* redisplay cursor */
{
if (++cursor_flag == 0)
{
set_drawpage(page);
lastpage = page;
draw_cursor(oldx, oldy, 0, page);
}
}
int move_2D(PDRIVER *d, int *x, int *y, unsigned *b)
{
int c;
if (d == NULL) return 0;
if (PNEW_POS & (c = mouse_read(d, x, y, b)))
cursor_move(*x, *y);
return c;
}
int move_till_click(PDRIVER *d, unsigned b, int *x, int *y) /* b is button mask */
{
int s;
unsigned c;
if (d == NULL) return -1;
while(1)
{
if (((s = move_2D(d, x, y, &c)) & PNEW_BUT) && (c & b)) break;
}
return s;
}
extern int manip_2D_avail;
extern int redraw;
int can_point_2D()
{
if (!manip_2D_avail)
{
popmsg("Mouse not available");
delay(500);
redraw = 1;
return 0;
}
return 1;
}
int move_and_select_2D(PDRIVER *d)
{
int x, y, c;
unsigned b;
if (!(c = move_2D(d, &x, &y, &b))) return 0; /* no changes */
b &= 1; /* only left button wanted */
if (check_controls(x, y, b)) return 0;
if (b != 0 && (c & PNEW_BUT)) /* new button: DOWN event */
{
OBJECT *obj;
obj = where_screen_pt(NULL, NULL, x, y);
if (obj)
{
set_obj_flags(obj, get_obj_flags(obj) ^ OBJ_HIGHLIGHTED);
if (get_obj_flags(obj) & OBJ_HIGHLIGHTED)
highlight_obj(obj);
else
unhighlight_obj(obj);
redraw = 1;
}
else
{
popmsg("Not on any object");
delay(300);
}
redraw = 1;
}
return 0;
}
/* find world coordinates of pointer based on given view */
void pointer_to_world(POINTER *p, VIEW *v, long *x, long *y, long *z)
{
MATRIX n;
*x = p->x;
*y = p->y;
*z = p->z;
view_to_matrix(v,n);
matrix_point(n,x,y,z);
p->wpos[3][0] = *x;
p->wpos[3][1] = *y;
p->wpos[3][2] = *z;
p->wpos_valid = 1;
}
/* rotate data to view alignment */
void rotate_to_view( VIEW *v, long *x, long *y, long *z)
{
MATRIX n;
view_to_matrix(v,n);
matrix_rotate(n,x,y,z);
}
/***************** GLOVE CURSOR SUPPORT *************/
static SEGMENT *wrist_seg[2]; // wrist-on-body segment
// also used to manip. objects
static SEGMENT *glove_seg[2]; // wrist twist for presentation
static SEGMENT *glove_joints[2][20]; // joints on hand
#define Y_GLV_OFFSET 0 // needed as "body" is at neck level
#define GLOVE_DIST 1000
#define SELECT_LENGTH 20 // distance along last index finger segment
/* to selection point */
int glove_update(PDRIVER *d, POINTER *p, int which) // read glove, update positions
{
int c;
c = pointer_read(d, p, which);
if ((c & (PNEW_POS | PNEW_ROT | PNEW_FLEX)) == 0) return 0;
abs_move_segment((wrist_seg[which]), p->x, p->y + Y_GLV_OFFSET, p->z + GLOVE_DIST);
if (d->pdata->type&P_IS6DG)
abs_rot_segment((wrist_seg[which]), p->rx, p->ry, p->rz, RYXZ);
else
abs_rot_segment((glove_seg[which]), -2000L*p->y, p->ry, -4000L*p->x, RYXZ);
if ((!glove_joints[which][1]) && (!glove_joints[which][10])) {
redraw = 1;
return 1;
}
if (glove_Polarity(which)) {
abs_rot_segment(glove_joints[which][1], 0L,30*65536L+18061L*p->flex[0],0L, RYXZ);
abs_rot_segment(glove_joints[which][2], -20*65536L,90*65536L,-5*65536L+38700L*p->flex[1], RYZX);
}
else {
abs_rot_segment(glove_joints[which][1], 0L,-30*65536L-18061L*p->flex[0],0L, RYXZ);
abs_rot_segment(glove_joints[which][2], 20*65536L,90*65536L,5*65536L+38700L*p->flex[1], RYZX);
}
abs_rot_segment(glove_joints[which][3], 38700*p->flex[2],0L,0L, RYXZ);
abs_rot_segment(glove_joints[which][4], 38700*p->flex[3],0L,0L, RYXZ);
abs_rot_segment(glove_joints[which][5], 38700*p->flex[4],0L,0L, RYXZ);
abs_rot_segment(glove_joints[which][6], 38700*p->flex[5],0L,0L, RYXZ);
abs_rot_segment(glove_joints[which][7], 38700*p->flex[6],0L,0L, RYXZ);
abs_rot_segment(glove_joints[which][8], 38700*p->flex[7],0L,0L, RYXZ);
abs_rot_segment(glove_joints[which][9], 38700*p->flex[8],0L,0L, RYXZ);
abs_rot_segment(glove_joints[which][10],38700*p->flex[9],0L,0L, RYXZ);
redraw = 1;
return 1;
}
extern OBJLIST *objlist; /* only needed during load */
extern void *split_tree;
extern char *fix_fname(char *fname);
extern char loadpath[];
extern char cursorloadpath[];
int load_glove_cursor(SEGMENT *body_seg, PDRIVER *gd, char *glove_fname, int which)
{
// First, copy the glove cursor path into the loadpath.
// The loadpath must be saved so it can be restored later.
char temppath[100];
strcpy(temppath, loadpath);
strcpy(loadpath, cursorloadpath);
int i;
FILE *in;
OBJECT *obj;
if ((in = fopen(fix_fname(glove_fname), "r")) == NULL)
{
popmsg("Could not open glove file");
getkey();
strcpy(loadpath, temppath);
return -1;
}
set_readseg_objlist(objlist);
set_readseg_seglist(&(glove_joints[which][0]),20);
(wrist_seg[which]) = new_seg(body_seg);
if ((gd->pdata->type & P_IS6DG) == 0)
abs_rot_segment((wrist_seg[which]), 55*65536L, 0, 0, RYXZ); /* glove wrist pose */
(glove_seg[which]) = readseg(in, (wrist_seg[which]));
fclose(in);
if ((glove_seg[which]) == NULL)
{
popmsg("Bad glove figure file!");
getkey();
strcpy(loadpath, temppath);
return -2;
}
for(i = 0; i < 11; i++) /* glove is a non-selectable object */
{
obj = (OBJECT *)seg_get_object(glove_joints[which][i]);
set_obj_flags(obj, get_obj_flags(obj) | OBJ_NONSEL);
}
strcpy(loadpath, temppath);
return 0;
}
// 3D/6D CURSOR SUPPORT
static SEGMENT *cursor_seg;
#pragma argsused
int load_3D_cursor(SEGMENT *body_seg, PDRIVER *gd, char *cursor_fname)
{
// First, copy the glove cursor path into the loadpath.
// The loadpath must be saved so it can be restored later.
char temppath[100];
strcpy(temppath, loadpath);
strcpy(loadpath, cursorloadpath);
int i;
FILE *in;
OBJECT *obj;
if ((in = fopen(fix_fname(cursor_fname), "r")) == NULL)
{
popmsg("Could not open glove file");
getkey();
strcpy(loadpath, temppath);
return -1;
}
cursor_seg = new_seg(body_seg);
obj = load_plg(in);
fclose(in);
if (obj)
{
seg_set_object(cursor_seg, obj);
set_object_owner(obj, cursor_seg);
set_obj_flags(obj, get_obj_flags(obj) | OBJ_NONSEL);
add_obj_to_split_area((SPLIT *)split_tree, obj);
update_segment(cursor_seg);
strcpy(loadpath, temppath);
return 0;
}
else
{
popmsg("Bad pointer object file!");
getkey();
strcpy(loadpath, temppath);
return -2;
}
}
int cursor_update3D(PDRIVER *d, POINTER *p) // read pointer, update positions
{
int c;
c = pointer_read(d, p);
if ((c & (PNEW_POS | PNEW_ROT)) == 0) return 0;
abs_move_segment(cursor_seg, p->x, p->y + Y_GLV_OFFSET, p->z + GLOVE_DIST);
abs_rot_segment(cursor_seg, p->rx, p->ry, p->rz, RYXZ);
redraw = 1;
return 1;
}
// USED FOR 3D/6D MANIPULATION
extern int have_glove, use_glove, have_ptr;
#pragma argsused
SEGMENT *manip_data(PDRIVER *d, long *x, long *y, long *z, int which)
{
if (!have_ptr)
{
*x = 0;
*y = 0;
*z = SELECT_LENGTH;
matrix_point(*get_seg_pmatrix(glove_joints[which][4]), x, y, z);
return (wrist_seg[which]);
}
else
{
seg_getposxyz(cursor_seg, x ,y ,z);
return cursor_seg;
}
}