1 /* Copyright (C) 1992-1998 The Geometry Center
2  * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3  *
4  * This file is part of Geomview.
5  *
6  * Geomview is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * Geomview is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Geomview; see the file COPYING.  If not, write
18  * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
19  * USA, or visit http://www.gnu.org.
20  */
21 
22 
23 /* Authors: Stuart Levy, Tamara Munzner, Mark Phillips */
24 
25 #ifndef _DRAWER_H_
26 #define _DRAWER_H_
27 
28 #include "common.h"
29 #include "transformn.h"
30 #include "pick.h"
31 #include "mg.h"
32 
33 /* N-D color maps */
34 typedef struct cent {	/* Colormap entry */
35   float v;			/* projection value */
36   ColorA c;			/* color */
37   int interp;			/* interpolate values between cmap points */
38 } cent;
39 
40 typedef struct cmap {	/* Colormap table */
41   HPointN *axis;		/* projection axis */
42   vvec cents;			/* colormap; entries are 'cent's */
43   int coords;			/* ID of axis' coordinate system; default UNIVERSE */
44 } cmap;
45 #define MAXCMAP 4
46 
47 typedef struct NDstuff
48 {
49   mgNDctx mgNDctx;
50   TransformN *W2C;      /* World-to-Camera transform */
51   TransformN *T;	/* object-to-ND-camera transform, including
52 			 * the projection to the lower-dimensional
53 			 * sub-space.
54 			 */
55 
56 #if 0
57   Transform  MGFactor;  /* 4x4 transform handed over to the mg layer */
58   TransformN *rest;     /* remaining (Nd-4) lines, contained in the
59 			 * rows (4..Nd)
60 			 */
61   int *perm;            /* permuation on the rows of T */
62 #endif
63 
64   TransformN *W2c;      /* Universe-to-Color transform */
65   TransformN *Tc;	/* object-to-coloring-space-transform */
66   int ncm;		/* number of colormaps */
67   cmap *cm;		/* colormap array */
68   HPointN *hc;	/* work area for color projections */
69 } NDstuff;
70 
71 #define OBJECTFIELDS							\
72   char *name[2];        /* array of names */				\
73   Geom *Item;           /* For Geoms, the Inst holding the		\
74                          *  modelling transform; for DViews,		\
75                          *  an Inst pointing to the scene.		\
76                          *  In all cases this Inst holds any		\
77                          *  relevant Appearance.			\
78                          */						\
79   PFI updateproc;       /* motion update procedure */			\
80   Handle  *incrhandle;  /* Handle to above */				\
81   Transform Incr;       /* xform per frame update, if no updateproc */	\
82   int id;               /* my id */					\
83   int seqno;            /* sequence no for keeping track of changes */	\
84   bool redraw;          /* object needs redrawing */			\
85   bool moving;          /* moving -> Incr != identity || updateproc != NULL */ \
86   unsigned changed      /* Something about this obj changed; redraw */
87 
88 /* flags for the "changed" field */
89 #define CH_NOTHING      0
90 #define	CH_GEOMETRY	1
91 #define	CH_TRANSFORM	2
92 
93 typedef struct DObject {
94   OBJECTFIELDS;
95 } DObject;
96 
97 typedef struct DGeom {
98   OBJECTFIELDS;
99   Geom *Inorm;          /* Inst holding normalization transform */
100   Geom *Lgeom;          /* List node holding pointer to user's Geom */
101   Geom *Lbbox;          /* List node holding the pointer to our Bbox */
102   int  bbox_center;     /* bbox center as alien object */
103   bool bboxdraw;        /* boolean */
104   char normalization;   /* Normalization: NONE, EACH, or ALL */
105   bool bboxvalid;       /* bbox is valid */
106   bool pickable;        /* Is this Dgeom pickable ? */
107   int  bezdice;         /* Meshsize for diced up bezier patch */
108   Appearance *bboxap;
109   enum citizenship {ORDINARY, THEWORLD, ALIEN} citizenship;
110   TransformN *NDT, *NDTinv;     /* N-D transform and its inverse; NULL for 3-D objects */
111 
112 /* Ordinary DGeoms are subgeoms of Theworld DGeom.
113  * Theworld is the single DGeom containing the world transforms
114  * and all ordinary DGeoms.
115  * Alien DGeoms are in the Universe list but are not part of Theworld.
116  */
117 } DGeom;
118 
119 /* models of hyperbolic space; these must start with 0 and be
120    consecutive because they are used as indices in the browser */
121 typedef enum {
122   VIRTUAL=0,
123   PROJECTIVE,
124   CONFORMALBALL
125 } HModelValue;
126 
127 typedef struct DView {
128   OBJECTFIELDS;
129   Camera *cam;          /* The camera itself */
130   Handle *camhandle;    /* Handle to above */
131   WnWindow *win;        /* The (abstract) window */
132   unsigned frozen;      /* flag: frozen: Don't attempt to redraw this view */
133   bool newcam;          /* flag: need to mgreshapeviewport() */
134   mgcontext *mgctx;     /* Window's mg context pointer */
135   int apseq;            /* seq no: has global default changed? */
136   float lineznudge;     /* millionths of Z-range by which lines lie closer
137                          * than surfaces */
138   Color backcolor;      /* Window background color */
139   bool cameradraw;      /* Do we draw cameras in this view? */
140   Geom *hsphere;        /* hsphere at infy for use in hyp mode; when NULL
141                            don't draw it, otherwise draw it */
142   HModelValue hmodel;   /* model of hyperbollic space for this camera; value
143 			   is one of VIRTUAL, PROJECTIVE, CONFORMAL, and is
144                            meaningful only when viewing hyperbolic geometry */
145   PFV extradraw;        /* function to draw any extra stuff in this window */
146   Keyword stereo;       /* {NO,HORIZONTAL,VERTICAL}_KEYWORD: stereo style */
147   int stereogap;        /* gap between subwindows in stereo mode        */
148   WnPosition vp[2];     /* Subwindow viewports, if stereo != MONO       */
149   mgshadefunc shader;   /* Software shader function (NULL -> hardware)  */
150   int NDPerm[4];        /* N-D -> 3-D axis permutation */
151   int nNDcmap;
152   cmap NDcmap[MAXCMAP]; /* N-D color map */
153   struct NDcam *cluster;/* to which cluster do we belong?  NULL if not N-D */
154 } DView;
155 
156 /* flags for "frozen" */
157 #define UNFROZEN    0
158 #define SOFT_FROZEN 1
159 #define HARD_FROZEN 2
160 
161 typedef struct NDcam {
162   char		*name;		/* camera-cluster name */
163   TransformN	*C2W, *W2C;	/* N-D camera-to-universe transform */
164   struct NDcam  *next;		/* next N-D camera */
165 } NDcam;
166 
167 /*
168  * The array of DGeoms is a flat structure with pointers into the
169  * following OOGL hierarchy:
170  *
171  *
172  * drawerstate.universe -->     LIST -------- LIST --- LIST... [rest of Aliens]
173  *				  |		|  	|
174  *				  |  	      INST    INST
175  *				  |	      [Alien] [Alien]
176  *				  |
177  * 				drawerstate.world == dgeom[0]:
178  *				  |
179  * dgeom[0]->Item  -->		INST        [world modelling xform]
180  *		 	        [Theworld]
181  *				  |
182  * dgeom[0]->Inorm  -->		INST        [world normalizing xform]
183  *				  |
184  * dgeom[0]->Lgeom --> 	LIST  -----  LIST --- ... [all ordinary DGeoms]
185  *				[Ordinary]  [Ordinary]
186  *				  |
187  *				DGeom[x]:
188  *				  |
189  *				INST (= Item) [modelling xform, appearance]
190  *		  		  |
191  *		  		  |
192  *				INST (= Inorm) [normalization xform]
193  *		  		  |
194  *		  		  |
195  *				LIST (= Lgeom) -------- LIST (= Lbbox)
196  *				  |			  |
197  *				[user's Geom]   [BBox of user's Geom, or NULL]
198  *
199  * Note that the world appearance is *not* dgeom[0]->Item->ap, which
200  * is always NULL.
201  * Changes to the world appearance are broadcast to all individual dgeoms.
202  * worldap is kept around in drawer.c to let the ui know how to
203  * set control panels when the world is the target.
204  */
205 typedef struct DrawerState {
206 
207   int 		      pause;	/* hiatus on emodule input? */
208   float		 lastupdate;	/* Time (seconds since program began) of last xfm update */
209   DView		    defview;	/* default DView */
210   WnPosition         winpos;	/* screen position of current mg context's window */
211   int         normalization;	/* NONE, EACH, KEEP, or ALL (default EACH) */
212   int                 space;	/* TM_EUCLIDEAN, TM_HYPERBOLIC,
213 				   TM_SPHERICAL (default EUC) */
214   int		    changed;	/* Flag: geom or camera or something changed,
215 				 * must redraw. */
216   Appearance *           ap;	/* Default appearance: backstop + .v.ap */
217   int		      apseq;	/* Sequence number of default appearance;
218 				 * each drawer mg context should reexamine ap
219 				 * if drawerstate.apseq != view->apseq
220 				 */
221   Geom *	      world;	/* Everything in the world, including
222 				 * global modelling xform & appearance.
223 				 */
224   Geom *           universe;	/* List of everything in the universe:
225 				 * world and aliens. */
226 
227   int		   NDim;	/* Dimension of all ND items */
228   NDcam		  *NDcams;	/* List of all ND camera clusters, or NULL */
229 #ifdef MANIFOLD
230 
231 #define MTMAX 500
232 #define DVMAX 50
233 
234   Transform		MT[MTMAX];/* manifold transforms */
235   int			nMT;	  /* number of transforms actually in MT */
236   HPoint3		DV[DVMAX];/* vertices of manifold Dirichlet domain */
237   int			nDV;	  /* number of vertices actually in DV */
238   float			d1, i1;
239 #endif
240 
241   float			motionscale; /* set by user; used in scaling some
242 					(not all) motions */
243 
244   Geom			*camgeom;    /* Object used when drawing cameras */
245   int			 camproj;    /* Apply camera's projection to it? */
246 
247   /* drawerstate.world is the first node in drawerstate.universe
248    * dgeom[0]->Item == drawerstate.world
249    * dgeom[0]->Inorm is the child of the above
250    * dgeom[0]->Lgeom is the child of dgeom[0]->Inorm
251    */
252 } DrawerState;
253 
254 
255 /*
256  * LOOPGEOMS(i,dg) loops over all defined geoms; for each defined
257  * geom, int i is the index in the dgeoms array, and DGeom *dg
258  * points to the geom.  Usage:
259  *   LOOPGEOMS(i,dg) {
260  *     < body of loop --- use i and dg as needed >
261  *   }
262  * Note we skip dgeom[0], since it's by definition the entire world.
263  */
264 #define LOOPGEOMS(i,dg) \
265   for (i=1; i<dgeom_max; ++i) if ( (dg=dgeom[i]) != NULL)
266 
267 /*
268  * LOOPSOMEGEOMS(i,dg,cit) is like LOOPGEOMS but only returns ordinary DGeoms
269  */
270 
271 #define LOOPSOMEGEOMS(i,dg,cit) \
272   for (i=1; i<dgeom_max; ++i) if ( (dg=dgeom[i]) && (dg->citizenship==cit) )
273 
274 /*
275  * LOOPVIEWS(i,dv) is like LOOPGEOMS but for views.
276  */
277 #define LOOPVIEWS(i,dv) \
278   for (i=0; i<dview_max; ++i) if ( (dv=dview[i]) != NULL)
279 
280 
281 /* Broadcast by looping the correct array if index == ALLINDEX
282  * else broadcast to all dgeoms that are not aliens if id == WORLDGEOM
283  * else don't go through loop at all if improper index
284  * else just go through for loop once if index is normal.
285  * Obj is set to correct value on each pass through the loop.
286  *
287  * int i is index in the dgeoms or views array,
288  * type is T_GEOM or T_CAM (or T_NONE if either is acceptable),
289  * and objtype *obj is set to successive elements in the dgeoms/views array.
290  *
291  * Usage:
292  *  MAYBE_LOOP(id,i,type,objtype,obj) {
293  *    < body of loop: use i and obj as needed >
294  *                    is set correctly on any given pass through the loop >
295  *  }
296  */
297 
298 #define MAYBE_LOOP(id, i, type, objtype, obj) \
299     for(i = 0; (obj = (objtype *)drawer_next_bcast(id, &i, type)); i++)
300 
301 #define MAYBE_LOOP_ALL(id, i, type, objtype, obj) \
302     for(i = 0; (obj = (objtype *)drawer_next_object(id, &i, type)); i++)
303 
304 
305 /*
306  * An ID encodes an index (int) and a type (cam or geom).
307  */
308 #define	T_NONE	0
309 #define T_GEOM  1
310 #define T_CAM	2
311 #define	T_MAX	3	/* Max T_* value plus one */
312 
313 #define	GEOMID(i)	((i)<<2 | T_GEOM)	/* Geometric object #i */
314 #define	CAMID(i)	((i)<<2 | T_CAM)	/* Camera #i */
315 #define	NOID		((0)<<2 | T_NONE)
316 #define ID(type,i)	((i)<<2 | type)
317 
318 #define	ISGEOM(id)	(((id) & 3) == T_GEOM)
319 #define	ISCAM(id)	(((id) & 3) == T_CAM)
320 #define ISTYPE(type,id)	(((id) & 3) == type)
321 #define TYPEOF(id)	 ((id) & 3)
322 
323 #define	INDEXOF(id)	((id) >> 2)
324 
325 #define	ALLINDEX	-1
326 #define	WORLDGEOM	GEOMID(0)
327 
328 #define	FOCUSID		CAMID(-4)
329 					/* these are not necessarily geoms! */
330 #define TARGETID	GEOMID(-5)	/* "current target" */
331 #define CENTERID	GEOMID(-8)	/* "current center" */
332 
333 #define TARGETGEOMID	GEOMID(-6)	/* "current target geom" */
334 #define TARGETCAMID	CAMID(-7)	/* "current target cam" */
335 #define	DEFAULTCAMID	CAMID(-5)
336 
337 #define	SELF		GEOMID(-9)	/* "this geomview object" */
338 #define	UNIVERSE	GEOMID(-10)	/* the universe (as coordinate system) */
339 #define	PRIMITIVE	GEOMID(-11)	/* this picked OOGL primitive (coord system) */
340 #define BBOXCENTERID    GEOMID(-12)     /* center of bbox object */
341 
342 #define ALLCAMS		CAMID(ALLINDEX)
343 #define ALLGEOMS	GEOMID(ALLINDEX)
344 
345 typedef enum {
346   DRAWER_NOKEYWORD = 1,
347   DRAWER_NEAR,
348   DRAWER_FAR,
349   DRAWER_FOV,
350   DRAWER_FOCALLENGTH,
351   DRAWER_KA,
352   DRAWER_KS,
353   DRAWER_KD,
354   DRAWER_SHININESS,
355   DRAWER_NORMSCALE,
356   DRAWER_LIGHT_INTENSITY,
357   DRAWER_LINE_ZNUDGE,
358 
359   DRAWER_FACEDRAW,
360   DRAWER_EDGEDRAW,
361   DRAWER_VECTDRAW,
362   DRAWER_NORMALDRAW,
363   DRAWER_TEXTUREDRAW,
364   DRAWER_TEXTUREQUAL,
365   DRAWER_SHADELINES,
366   DRAWER_CONCAVE,
367   DRAWER_BACKCULL,
368   DRAWER_SHADING,
369   DRAWER_LINEWIDTH,
370   DRAWER_PERSPECTIVE,
371   DRAWER_EVERT,
372   DRAWER_BBOXDRAW,
373   DRAWER_NORMALIZATION,
374   DRAWER_SAVE,
375   DRAWER_PROJECTION,
376   DRAWER_BEZDICE,
377   DRAWER_CAMERADRAW,
378   DRAWER_PICKABLE,
379   DRAWER_HSPHERE,
380   DRAWER_DOUBLEBUFFER,
381   DRAWER_APOVERRIDE,
382 
383   DRAWER_DIFFUSE,
384   DRAWER_EDGECOLOR,
385   DRAWER_NORMALCOLOR,
386   DRAWER_BBOXCOLOR,
387   DRAWER_BACKCOLOR,
388   DRAWER_LIGHTCOLOR,
389 
390   DRAWER_TRANSLUCENCY,
391   DRAWER_ALPHA,
392 
393   DRAWER_INERTIA,
394   DRAWER_CONSTRAIN,
395   DRAWER_OWNMOTION
396 } DrawerKeyword;
397 
398 extern DView **		dview;
399 extern DGeom **		dgeom;
400 extern DrawerState	drawerstate;
401 extern int		dgeom_max;
402 extern int		dview_max;
403 
404 extern TransformStruct ts_identity;
405 
406 DObject *    drawer_get_object( int id );/* Get DObject * for object 'id' */
407 DObject * drawer_next_object( int id, int *indexp, int type );
408 DObject *drawer_next_bcast( int id, int *indexp, int type );
409 Appearance * drawer_get_ap( int id );	/* Get net appearance for DGeom 'id' */
410 
411 void	drawer_make_bbox(DGeom *dg, bool combine);
412 int	drawer_geom_count();
413 int	drawer_cam_count();
414 int	drawer_idbyctx( mgcontext *ctx );
415 bool	drawer_moving();	/* is anything (DGeom, DView) moving? */
416 int	drawer_idbyname(char *name);
417 char    *drawer_id2name(int id);
418 int     drawer_name2metaid(char *name);
419 int	drawer_objok(int id, int type);
420 int	drawer_pick( int id, int x, int y, Pick *pick);
421 void	drawer_init(char *apdefault, char *camgeometry, char *windefault);
422 
423 void	drawer_merge_baseap( ApStruct *as );
424 void	drawer_merge_camera( int id, Camera *cam );
425 void	drawer_merge_window( int id, WnWindow *win );
426 void	drawer_name_object(int id, int ni, char *name);
427 void	drawer_updateproc(int id, PFI func);
428 void	drawer_center(int id);
429 void	drawer_stop(int id);
430 void	drawer_pause(int pause);
431 void	drawer_set_window(int id, WnWindow *win);
432 void	drawer_snap_window(int id, char *fname);
433 void	drawer_init_dgeom(DGeom *dg, int id, enum citizenship citizenship);
434 void	drawer_nuke_world();
435 void	drawer_nuke_cameras(int keepzero);
436 void	drawer_get_transform(int id, Transform T, int cumulative);
437 TransformN *drawer_get_ND_transform(int from_id, int to_id);
438 TransformN *drawer_ND_CamView(DView *dv, TransformN *TN);
439 int	drawer_idmatch(int id1, int id2);
440 mgshadefunc softshader(int camid);
441 
442 NDstuff *drawer_init_ndstuff(DView *dv, TransformN *W2C, TransformN *W2U);
443 void drawer_destroy_ndstuff(NDstuff *nds);
444 void drawer_transform_ndstuff(NDstuff *nds, TransformN *T);
445 
446 void	drawer_float(int id, DrawerKeyword key, float fval);
447    /* key = DRAWER_NEAR, DRAWER_FAR, DRAWER_KA, DRAWER_KS,
448              DRAWER_KD, DRAWER_SHININESS, DRAWER_NORMSCALE,
449 	     DRAWER_LIGHT_INTENSITY */
450 
451 void	drawer_int(int id, DrawerKeyword key, int ival);
452    /* key = DRAWER_FACEDRAW, DRAWER_EDGEDRAW, DRAWER_NORMALDRAW,
453 	     DRAWER_SHADING, DRAWER_LINEWIDTH, DRAWER_PERSPECTIVE,
454 	     DRAWER_EVERT, DRAWER_BEZDICE, DRAWER_NORMALIZATION,
455 	     DRAWER_CAMERADRAW */
456 
457 void	drawer_color(int id, DrawerKeyword key, Color *col);
458    /* key = DRAWER_DIFFUSE, DRAWER_EDGECOLOR, DRAWER_NORMALCOLOR,
459             DRAWER_BBOXCOLOR, DRAWER_BACKCOLOR */
460 
461 float scaleof(int id);
462 int spaceof(int id);
463 extern Keyword hmodelkeyword(char *s, HModelValue val);
464 
465 void drawer_set_ap(int id, Handle *h, Appearance *ap);
466 
467 #ifdef MANIFOLD
468 
469 int drawer_read_manifold(char *file);
470 
471 #endif /* MANIFOLD */
472 
473 #endif /* ! _DRAWER_H_ */
474 
475 /*
476  * Local Variables: ***
477  * c-basic-offset: 2 ***
478  * End: ***
479  */
480