home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / vr_api.h < prev    next >
C/C++ Source or Header  |  1996-03-19  |  89KB  |  2,278 lines

  1. // FULLY DOCUMENTED VERSION
  2.  
  3. /*
  4.  This code is part of the VR-386 project, created by Dave Stampe.
  5.  VR-386 is a desendent of REND386, created by Dave Stampe and
  6.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  7.  Stampre for VR-386.
  8.  
  9.  Copyright (c) 1994 by Dave Stampe:
  10.  May be freely used to write software for release into the public domain
  11.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  12.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  13.  this software or source code into their products!  Usually there is no
  14.  charge for under 50-100 items for low-cost or shareware products, and terms
  15.  are reasonable.  Any royalties are used for development, so equipment is
  16.  often acceptable payment.
  17.  
  18.  ATTRIBUTION:  If you use any part of this source code or the libraries
  19.  in your projects, you must give attribution to VR-386 and Dave Stampe,
  20.  and any other authors in your documentation, source code, and at startup
  21.  of your program.  Let's keep the freeware ball rolling!
  22.  
  23.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  24.  REND386, improving programmer access by rewriting the code and supplying
  25.  a standard API.  If you write improvements, add new functions rather
  26.  than rewriting current functions.  This will make it possible to
  27.  include you improved code in the next API release.  YOU can help advance
  28.  VR-386.  Comments on the API are welcome.
  29.  
  30.  CONTACT: dstampe@psych.toronto.edu
  31. */
  32.  
  33. #include "vr_types.h"
  34.  
  35. #ifndef PTRBDEF
  36. typedef void PDRIVER;
  37. #endif
  38.  
  39. #ifndef PTRDEF
  40. typedef void POINTER;
  41. #endif
  42.  
  43.  
  44. /////////////////////////////////////////////////////
  45. ////                                             ////
  46. //// VR-386 API HEADER FILE AND DOCUMENTATION    ////
  47. ////                                             ////
  48. ////  8/1/94 BY DAVE STAMPE             ////
  49. ////                                             ////
  50. /////////////////////////////////////////////////////
  51.  
  52.  
  53. /////////////////////////////////////////////////////
  54. ////                                             ////
  55. //// OBJECTS: AN ENCAPSULATION METAPHOR FOR      ////
  56. ////                                             ////
  57. //// CREATION AND ANIMATION OF VIRTUAL WORLDS    ////
  58. ////                                             ////
  59. /////////////////////////////////////////////////////
  60.  
  61. // OBJECTS in VR-386 come in three flavors: fixed, moveable,
  62. // and invisible. All are pointed to by the OBJECT type.
  63. //
  64. // Fixed objects are visible but cannot be moved, and
  65. // make most efficient use of memory and processor time.
  66. //
  67. // Moveable objects are visible, and can be moved and
  68. // animated.  It is possible to convert objects between
  69. // fixed and moveable types.
  70. //
  71. // Invisible objects are equivalent to SEGMENTS in
  72. // REND386, and act as invisible links in a movement tree.
  73. // In fact, a moveable object is simply a fixed object
  74. // (a VISOBJ) associated with an invisible object (SEGMENT).
  75.  
  76. // An OBJECT pointer can point to either a VISOBJ or a
  77. // SEGMENT.  You can test what the pointer actually is
  78. // poining to with these macros:
  79.  
  80. #define is_object_visobj(p)   (*((WORD *)p)&IS_VISOBJ)
  81. #define is_object_segment(p)  (*((WORD *)p)&IS_SEGMENT)
  82.  
  83. // This function is more general:
  84.  
  85.     // tests if object visible
  86. BOOL is_object_visible(OBJECT *obj);
  87.  
  88. // You can test if an object is fixed with:
  89.  
  90. #define is_object_moveable(p) (*((WORD *)p)&IS_MOVEABLE)
  91.  
  92. // The segments used to move CAMERAs and LIGHTs, as well
  93. // as the body_seg and head_seg associated with the
  94. // VR body cannot be directly deleted, and are marked
  95. // as system owned.  They can be identified with:
  96.  
  97. #define is_system_owned(p)    (*((WORD *)p)&SYSTEM_OWNED)
  98.  
  99. // To use older REND386 segment functions, you must
  100. // convert the object to a segment.  You can do this
  101. // conversion with the following functions:
  102. // (These return NULL if given a NULL argument)
  103.  
  104.     // pointer to VISOBJ of OBJECT: NULL if inviible object
  105. VISOBJ  *object2visobj(OBJECT *p);
  106.  
  107.     // pointer to SEGMENT of OBJECT: NULL if fixed object
  108. SEGMENT *object2segment(OBJECT *p);
  109.  
  110. // also see make_fixed_object_moveable() below.
  111.  
  112. /////////////////////////////////////////////////////
  113. ////                                             ////
  114. //// OBJECT SELECTION                            ////
  115. ////                                             ////
  116. /////////////////////////////////////////////////////
  117.  
  118. // OBJECTs may have several characteristics.  Selected
  119. // objects appear highlighted (outlined in wireframe).
  120. // An object is selected by highlighting it, either
  121. // explicitly or by clicking on it with the mouse:
  122.  
  123.     // set highlight flag
  124. void highlight_object(OBJECT *obj);
  125.  
  126.     // resets highlight flag
  127. void unhighlight_object(OBJECT *obj);
  128.  
  129.     // tests if visible and selected
  130. BOOL is_object_selected(OBJECT *obj);
  131.  
  132. // Some objects can be made unselectable: for example, pointers
  133. // or the user's body.  You can test or set this with:
  134.  
  135.     // tests if object can be selected
  136. BOOL is_object_selectable(OBJECT *obj);
  137.  
  138.     // force object to be unselectable
  139. void make_object_unselectable(OBJECT *obj);
  140.  
  141. /////////////////////////////////////////////////////
  142. ////                                             ////
  143. //// OBJECT LISTS                                ////
  144. ////                                             ////
  145. /////////////////////////////////////////////////////
  146.  
  147. // OBJECTS are organized in several ways.  For storing
  148. // or manipulating several objects, they can be placed
  149. // on an OBJLIST.  This is a double-linked list allowing
  150. // for rapid removal.  Each list has a header to allow
  151. // easier removal of the first object in the list.  The
  152. // list holds the VISOBJ part of objects, and cannot hold
  153. // invisible objects (segments).
  154. // OBJLISTs are used to store loaded objects for
  155. // processing before they are inserted into the
  156. // world, and there is a list (inactive_object_list)
  157. // containing objects removed from the world (i.e.
  158. // alternative versions of objects).
  159. //
  160. // OBJLISTs should only be used to hold objects that
  161. // are not in the world itself, since the objects in the
  162. // world are held in "area" OBJLISTs, and switch between
  163. // OBJLISTs if they are updated or moved.
  164.  
  165. // OBJLISTS headers can be created to attach objects to, or you can
  166. // use the pre-created system OBJLIST default_objlist:
  167.  
  168. extern OBJLIST * default_objlist;       // used for loading objects
  169. extern OBJLIST * inactive_object_list;  // all objects not currently in world
  170.  
  171.     // create a new objlist
  172. OBJLIST *new_objlist();
  173.  
  174. // These functions dispose of OBJLIST headers
  175. // If the list is not empty, they keep or destroy
  176. // the VISOBJs on the list
  177.  
  178.     // delete objects on list then delete objlist
  179. void delete_objlist_and_objects(OBJLIST *list);
  180.  
  181.     // delete objlist, but just remove objects from list
  182.     // safer if not sure all objects are off list
  183. void delete_objlist_keeping_objects(OBJLIST *list);
  184.  
  185. // These functions place or remove objects to an OBJLIST.
  186. // It is not recommended to handle world objects diectly:
  187. // remove or add objects to the world using functions in
  188. // the WORLD section first:
  189.  
  190.        // drop object from list it's on
  191. void remove_from_objlist(OBJECT *obj);
  192.  
  193.      // put object at head of list
  194.      // remove if already on any list
  195. void add_to_objlist(OBJLIST *list, OBJECT *obj);
  196.  
  197. // Merging OBJLISTS is safe: Especially useful to add
  198. // lists of loaded objects to the inactive_object_list
  199.  
  200.     // removes all from <from>, adds to start of <to>
  201. void merge_objlists(OBJLIST *from, OBJLIST *to);
  202.  
  203. // In many cases, you need to perform a function on all
  204. // objects in a list.  Leter we will see similar "walking"
  205. // functions for object trees and the world.
  206.  
  207. void walk_objlist(OBJLIST *objlist, void (*fn)(OBJECT *));
  208.  
  209. // These are object list-status functions, included for completeness
  210.  
  211.     // is it currently in a list?
  212. BOOL on_any_objlist(OBJECT *obj);
  213.  
  214.     // look for head of list object is in.
  215. OBJLIST *which_objlist(OBJECT *obj);
  216.  
  217. OBJECT *first_in_objlist(OBJLIST *objlist);
  218. OBJECT *next_in_objlist(OBJECT *obj);
  219. OBJECT *prev_in_objlist(OBJECT *obj);
  220. BOOL is_first_in_objlist(OBJECT *obj);
  221. BOOL is_last_in_objlist(OBJECT *obj);
  222.  
  223.  
  224. /////////////////////////////////////////////////////
  225. ////                                             ////
  226. //// OBJECT TREES, ATTACHMENT AND LINKED MOTION  ////
  227. ////                                             ////
  228. /////////////////////////////////////////////////////
  229.  
  230. // OBJECTS may be attached to each other for the purpose
  231. // of controlling motion.  The links between objects are
  232. // "joints", which may be moved or rotated.  Many objects
  233. // can descend from one "parent" object, and will all move
  234. // as if part of the parent object when it moves, with
  235. // additional effects from their own joints.
  236. //
  237. // Effectively, there are two "poses" (combinations of
  238. // position and rotation) for each object: the "local"
  239. // or "joint" position, which is the difference between
  240. // the parent and "child" object poses.  The "world" pose
  241. // is the actual pose that the object has in the world,
  242. // which is the composite of the parent object's world pose
  243. // and the joint pose of the object.
  244. //
  245. // An object tree can be considered to be a single articulated
  246. // object, with the "root" object being used to move the object
  247. // in the world.  This root object (and any object in the tree)
  248. // may be visible or invisible.
  249.  
  250. // The basic operation is to attach and detach objects from the
  251. // tree.  Because the pose of the object depends on that of its
  252. // parent object, the joint pose is rarely the same as that of
  253. // the world pose when the object is attached.  So we must choose
  254. // whether to preserve the joint or world pose of an object when
  255. // attaching or detaching it.  While we could always choose to
  256. // preserve world pose when attaching or detaching objects, it's
  257. // somewhat expensive on processor time since we may want to immediately
  258. // reset the joint pose of the object.
  259.  
  260.      /* assumes parent is updated! */
  261.      // preserves world position if flagged
  262. void attach_object(OBJECT *obj, OBJECT *to, BOOL preserve);
  263.  
  264.     // this is the least expensive attach, and
  265.     // does no updates or calculations
  266.     // be sure to update <to> later!
  267. void naked_attach_object(OBJECT *obj, OBJECT *to);
  268.  
  269.     // detaches object: preserves world position if flagged
  270. void detach_object(OBJECT *obj, BOOL preserve);
  271.  
  272. // Here are some informational functions for object trees:
  273.  
  274.     // finds the basic object of a tree
  275. OBJECT *find_root_object(OBJECT *obj);
  276.  
  277.     // tests relationship of objects
  278. BOOL is_object_child_of(OBJECT *parent, OBJECT *child);
  279.  
  280.     // tests for any relationship of objects
  281.     // i.e. are they in the same tree?
  282. BOOL are_object_related(OBJECT *o1, OBJECT *o2);
  283.  
  284.  
  285. // Much like the OBJLIST-walk functions, these functions will
  286. // execute a function for each object in the tree.  They can
  287. // process objects that have certain characteristics.  They can either
  288. // process the given object and its decendants, or all objects
  289. // in the same tree as the object.
  290.  
  291. // object and children:
  292.  
  293.     // execute for object and descendants
  294. void do_for_all_child_objects(OBJECT *obj, void(* fn)(OBJECT *));
  295.  
  296.     // execute for objects and descendants-- ONLY visible objects
  297. void do_for_visible_child_objects(OBJECT *obj, void(* fn)(OBJECT *));
  298.  
  299.     // execute for objects and descendants-- ONLY highlighted objects
  300. void do_for_selected_child_objects(OBJECT *obj, void(* fn)(OBJECT *));
  301.  
  302. // all objects in tree:
  303.  
  304.     // execute for entire object tree-- ONLY visible objects
  305. void do_for_visible_related_objects(OBJECT *obj, void(* fn)(OBJECT *));
  306.  
  307.     // execute for entire object tree
  308. void do_for_all_related_objects(OBJECT *obj, void(* fn)(OBJECT *));
  309.  
  310.     // execute for entire object tree-- ONLY highlighted objects
  311. void do_for_selected_related_objects(OBJECT *obj, void(* fn)(OBJECT *));
  312.  
  313.  
  314. // You may also want to delete the objects in the tree
  315. // completely.  This can be done for the children of the
  316. // object, or for the entire tree if find_root_object(obj) is
  317. // used.
  318.  
  319.     // delete object, descendents and objects
  320. void delete_object_and_children(OBJECT *obj);
  321.  
  322.  
  323. /////////////////////////////////////////////////////
  324. ////                                             ////
  325. //// OBJECT POSE, MOTION AND UPDATING            ////
  326. ////                                             ////
  327. /////////////////////////////////////////////////////
  328.  
  329. // OBJECT motion in VR-386 has several stages to increase efficiency.
  330. // In the first stage, moveable objects may have their "pose"
  331. // (position and rotation) modified individually.  Since any
  332. // descendent object may have their position affected by this,
  333. // the effect of all motions must be propagted through the tree
  334. // by and update step.  (This step is done automatically by
  335. // animation functions, as we'll see later).
  336. //
  337. // Finally, the renderer will determine which objects are visible
  338. // and complete the movement of the object by recomputing their
  339. // vertex positions.  Each vertex in a VR-386 object has two
  340. // sets of coordinates: object (ox,oy,oz) which determine the object
  341. // shape, and world (x,y,z) which are updated by the renderer by
  342. // computing them from object world pose and the object coordinates.
  343. //
  344. // Internally, the SEGMENT part of an object contains two matrices:
  345. // a world-position (pmatrix) and a joint position (jmatrix).
  346. // The world matrix is modified by any motions of objects theat the
  347. // object is attached to; the jmatrix is modified by setting object
  348. // pose or by attaching/detaching the object from others.
  349. // To find the true pose of the object (world or joint) may require
  350. // that we look at the angles in the matrix rather than the cached
  351. // record of the last pose change.  This is somewhat more expensive,
  352. // but is sometimes needed..
  353.  
  354. // A POSE is the basic structure used for movement in VR-386.
  355. // It has the following definition:
  356. //
  357. // typedef struct  {
  358. //             COORD x,y,z;
  359. //            ANGLE rx,ry,rz;
  360. //           } POSE;
  361. //
  362. // A special value for the fields of the POSE is:
  363. //
  364.     #define DONTCARE 0x80000000L
  365. //
  366. // which says that the position or angle of that entry is unspecified,
  367. // and (if the POSE is being applied to an object) that the value
  368. // of that part of the current object pose will not be changed.
  369. //
  370. // Two predefined values for initializing POSE structures are defined:
  371.  
  372. #define DONTCARE_POSE { DONTCARE,DONTCARE,DONTCARE,DONTCARE,DONTCARE,DONTCARE }
  373. #define ZERO_POSE { 0,0,0,0,0,0 }
  374.  
  375. // For example, most POSE structures should be initialized to ZERO_POSE.
  376. // You can use DONTCARE_POSE initialization if you're only going to be
  377. // changing a few field of the object pose, for example:
  378. //
  379. // POSE p, pp = DONTCARE_POSE;
  380. // get_object_pose(obj, &p);
  381. // pp.rx = p.x + float2angle(5);
  382. // set_object_pose(obj, &pp);
  383. //
  384. // which will increase the rotation angle about the X axis of the object's
  385. // joint (or world, if the object is unattached) by 5 degrees.
  386.  
  387. // Here are object pose functions:
  388.  
  389.     // get local "joint" pose of object if moveable
  390. void get_object_pose(OBJECT *obj, POSE *p);
  391.  
  392.     // get "real" pose from joint matrix in object
  393. void get_object_matrix_pose(OBJECT *obj, POSE *p);
  394.  
  395.     // get global physical pose of object from world matrix
  396. void get_object_world_pose(OBJECT *obj, POSE *p);
  397.  
  398.     // set the "joint" pose of object
  399.     // ignores DONTCARE values in pose
  400. void set_object_pose(OBJECT *obj, POSE *p);
  401.  
  402.     // place object in world, even if attached!
  403.     // can be expensive, especially if DONTCARES used
  404. void set_object_world_pose(OBJECT *obj, POSE *p);
  405.  
  406.     // faster way to get object position than world_pose
  407. void get_object_world_position(OBJECT *obj, COORD *x, COORD *y, COORD *z);
  408.  
  409. // There are also a lot of older SEGMENT-based REND386 functions available.
  410. // If you use these, be sure to use object2segment() to do the
  411. // translation first!
  412.  
  413. // Updating of the object tree proceeds from the specified object
  414. // down through its descendents.  The objects are scanned to see
  415. // if any have changed: if so, the world pose of the changed
  416. // object and all its descendents are recomputed.
  417. //
  418. // Updating is also essential if an object has been changed
  419. // in any way, so that the changes will be registered to the
  420. // world position.  Major changes (e.g in object scale or
  421. // changes in object vertex positions) will require more
  422. // drastic "physical" updating.  These will be discussed further
  423. // for object creation and loading:
  424.  
  425.     // checks if moved; recomputes world position
  426. void update_object(OBJECT *obj);
  427.  
  428.     // recomputes object normals, bounding sphere
  429.     // and if moved: current representation only
  430. void physical_update_object(OBJECT *obj);
  431.  
  432.     // massive update: recomputes all object's reps,
  433.     // forces all connecting objects to update position
  434. void global_update_object(OBJECT *obj);
  435.  
  436.  
  437. /////////////////////////////////////////////////////
  438. ////                                             ////
  439. ////  ANIMATION AND AUTOMATIC UPDATING           ////
  440. ////                                             ////
  441. /////////////////////////////////////////////////////
  442.  
  443. // NOT FULLY COMPLETED: ALL LISTED ARE FUCTIONAL
  444.  
  445. // Animation control is a set of functions to allow autonomous
  446. // motion of objects without the need to move objects each
  447. // frame.  In the future, functions such as TWEEN will be added.
  448. // As of now, the critical step is an auto-update system for
  449. // efficient calculation of changed objects, used by STATMACH.C
  450. // for now.
  451. //
  452. // When many joints of a figure (objects in a tree) are moved
  453. // it is crucial not to update each joint individually, as this
  454. // would cause objects to be recomputed many times.  Instead,
  455. // a list is created of the root objects of the tree of moved
  456. // objects.  Then after all animation is complete, the object
  457. // updates may be done quickly.  YOU are responsible for updating
  458. // moved objects unless the animation system has moved them!
  459. //
  460. // Objects are automatically updated when attached or detached.
  461. // Because the tree structure is changed, during animation it
  462. // is important to do any attach or detach operations BEFORE
  463. // moving objects.
  464.  
  465.     // puts root of tree on update list if not there
  466.     // just pass the object that was move: the code will do the rest
  467. void add_to_object_update_list(OBJECT *obj);
  468.  
  469.     // does the update on all moved objects, then
  470.     // removes them from the update list
  471.     // returns nonzero if update was needed, so
  472.     // you can tell if rendering is needed.
  473. BOOL process_object_update_list();
  474.  
  475. // Sometimes objects must be removed from the list: before
  476. // deleting objects or worlds, for example.  Usually it's
  477. // better to simply process the list.
  478.  
  479.     // fast remove deleted segments
  480. void remove_from_object_update_list(OBJECT *obj);
  481.  
  482.     // dump entire update list
  483. void clear_object_update_list();
  484.  
  485.  
  486.  
  487. /////////////////////////////////////////////////////
  488. ////                                             ////
  489. ////  THE WORLD                         ////
  490. ////                                             ////
  491. /////////////////////////////////////////////////////
  492.  
  493. // UNDER CONSTRUCTION: NOT ALL FULLY FUNCTIONAL
  494.  
  495. // In VR-386, a WORLD serves to organize a set of objects into
  496. // an environment.  Eventaully, this environment may be loaded
  497. // or deleted, or the user may switch between worlds.
  498. //
  499. // For objects, the world is a visibility structure (a SPLIT tree),
  500. // containing all visible objects in to world.  Objects that are
  501. // not visible (e.g. alternate forms of an object) should be
  502. // placed in the inactive_object_list OBJLIST, so they may be
  503. // deleted when the world is terminated.  Or they may just be
  504. // left off any list, if you take responsibility for their
  505. // deletion.  Note that only VISOBJ (visible part of moveable
  506. // or fixed objects) are part of the world: invisible objects
  507. // (SEGMENTS) are not so you must use care to delete them
  508. // when disposing of a world.
  509. //
  510. // The visibility tree consists of SPLITs: 3-D planes that divide
  511. // the world into AREAs.  As yet, there is little support in the
  512. // API for AREAs: there is a lot of work to be done on and with
  513. // them in the future.
  514. //
  515. // For now, you should be able to:
  516. // -create the startup, default WORLD (TESTED)
  517. // -make new WORLDs (but be careful loading them!) (??)
  518. // -switch between WORLDS (??)
  519.  
  520. // These are the currently defined WORLD functions:
  521.  
  522.     // save current camera, visibility tree, inactive list,
  523.     // and user position to WORLD w
  524. void save_world_state(WORLD *w);
  525.  
  526.     // restore old WORLD w
  527. void restore_world_state(WORLD *w);
  528.  
  529.     // create WORLD, save current WORLD data to it
  530.     // <template> arg not yet used
  531. WORLD *create_world(WORLD * template);
  532.  
  533.     // just releases WORLD struct now
  534.     // In the future, will delete everything in the world
  535. void release_world(WORLD *w);   // NOT YET FUNCTIONAL
  536.  
  537.     // for initialization, creates all the default
  538.     // objects, structures, lists and so on
  539.     // creates a WORLD <default_world>
  540. void create_default_world();
  541.  
  542.     // DON'T  USE until a better world file format is developed!
  543.     // for now, use read_world() to load a REND386 compatible
  544.     // world.
  545. void load_world(FILE *in, WORLD *w); // NOT FUNCTIONAL
  546.  
  547. // These items are manipulated by changing the WORLD, and
  548. // form the roots of world structures:
  549.  
  550. extern WORLD *default_world;    // the default world (startup)
  551. extern WORLD *current_world;    // the WORLD currently in use
  552.  
  553. extern SPLIT *global_world_root;   // the root of current visibility tree
  554. extern SPLIT *current_split;       // used to add objects to splits
  555.  
  556. extern OBJLIST *default_objlist;      // used for loading objects
  557. extern OBJLIST *inactive_object_list; // all objects not currently in world
  558.  
  559.  
  560. // Objects when first loaded are not part of the world.  Objects
  561. // must be explicitly added to the world to become visible, and must
  562. // be removed from the world to make them invisible.
  563.  
  564. // To add objects to the world, use these functions:
  565.  
  566. void add_object_to_world(OBJECT *obj);
  567.  
  568. void add_objlist_to_world(OBJLIST *olist);
  569.  
  570. // Use this function to remove an object from the world.  The
  571. // objects will be placed in the inactive_object_list OBJLIST.
  572.  
  573. void remove_object_from_world(OBJECT *obj);
  574.  
  575. // When creating worlds with walls or other visibility-error prone
  576. // features, SPLITs must be used.  They are also useful for dividing
  577. // the world into AREAs.  A SPLIT is a plane, specified by a point
  578. // on it and a normal to its surface.  Normals values should be
  579. // as large as possible: perhaps use a unit normal and convert it
  580. // with float2matval().  Set <flags> to zero for now.  The point
  581. // (x,y,z) should be somewhere near the center of the useful area of
  582. // the split, since it will be used to determine the AREA of the
  583. // world the split will subdivide.
  584. //
  585. // Any objects added to the world after a SPLIT has been created will
  586. // be attached to that SPLIT: for example, you'd create a split for
  587. // a room side then add an object to the world for that side of the room.
  588. // Once all SPLITs have been created and their objects loaded, call
  589. // end_of_world_splits().  All objects loaded after this will be
  590. // placed within AREAs.
  591. //
  592. // If not using SPLITs, just ignore them.  A default SPLIT at infinity
  593. // is created for each new world.
  594.  
  595.     // Adds a split to the WORLD.
  596.     // return FALSE if can't create it.
  597. BOOL add_split_to_world(COORD x, COORD y, COORD z,
  598.             COORD nx, COORD ny, COORD nz, WORD flags);
  599.  
  600.     // Marks end of SPLIT object loading, start of
  601.     // loading of rest of world objects.
  602. BOOL end_of_world_splits();
  603.  
  604.  
  605. //////// WORLD OBJECT TRAVERSALS
  606. // You often need to process all objects in the world
  607. // (usually to count objects, or to process selected
  608. // objects).  These functions apply a function to all
  609. // objects in the world.
  610.  
  611.     // for all objects not currently in world...
  612. void do_for_all_not_in_world(void (*fn)(OBJECT *));
  613.  
  614.     // for all objects in world...
  615. void do_for_all_objects(void (*fn)(OBJECT *));
  616.  
  617.     // for all selected (highlighted) in world...
  618. void do_for_all_selected(void (*fn)(OBJECT *));
  619.  
  620.     // for all moveable in world...
  621. void do_for_all_moveable(void (*fn)(OBJECT *));
  622.  
  623.     // for all fixed in world...
  624. void do_for_all_fixed(void (*fn)(OBJECT *));
  625.  
  626.     // for all selected, moveable in world...
  627. void do_for_all_selected_moveable(void (*fn)(OBJECT *));
  628.  
  629.  
  630.  
  631. /////////////////////////////////////////////////////
  632. ////                                             ////
  633. ////  LOADING OBJECTS AND FIGURES             ////
  634. ////                                             ////
  635. /////////////////////////////////////////////////////
  636.  
  637. // Objects in VR-386 are loaded as fixed objects, and are not
  638. // placed into the world.  You are responsible for placing the
  639. // objects into the world when you wish them to become visible.
  640. // Or you can place them onto the inactive_object_list OBJLIST
  641. // until needed.
  642. //
  643. // Objects are loaded from PLG files, which nmust have been
  644. // opened previously.  You can also load out of ANY text file:
  645. // for example, out of the middle of a world or .FIG file.  This
  646. // has not been used yet.  A change from REND386 .PLG files is
  647. // that the sum of the vertex counts for all polygones is needed.
  648. // This is an extra argument in the header line of the PLG file.
  649. // If no number is supplied, the file will be read twice.
  650. //
  651. // Objects loaded from PLG files are first scaled, then shifted
  652. // and finally rotated to create the vertices of the object.
  653. // Negative scales should NEVER be used, as visibility problems
  654. // will result.  The PLG vertex coordinates may be in floating point,
  655. // as are the scaling factors.  The rotation and shift affect the
  656. // "object-space" representation of the object, before it is moved
  657. // in the world.  This is similar the the <shift> in .FIG files, and
  658. // unlike the shift and rotate for moveable objects in REND386 .WLD
  659. // files.  The most important use for this is to position fixed objects
  660. // in the world, and to set the origin (0,0,0) point of objects, as this
  661. // is where it will rotate around when moved.
  662. //
  663. // The <depth> parameter says how the object will be sorted when
  664. // rendered.  0 will let the object's polys be sorted by deepest vertex,
  665. // 1 will cause them to be sorted by vertex midpoint.  Set bit 0x0100 to
  666. // have the object sorted as a unit, then polys within it sorted.
  667. // THE DEPTH PARAMETER WILL HAVE NEW FUNCTIONS IN THE FUTURE.
  668. //
  669. // Some objects may have multiple representations.  A representation
  670. // (REP) is the descripton of the visible part of an object, and
  671. // consists of its polys, colors, and vertices.
  672. // Multiple representations are usually used to increase rendering speed,
  673. // by letting distant (small) objects disappear or be drawn in a simpler
  674. // form than when close and large.  The size in pixels that the object
  675. // must subtend on the screen to be visible is set by the "size"
  676. // parameter, which may be set in the PLG file in the object name.
  677. // A representation of size 0 will always be seen, while larger "size"
  678. // representations can disappear if too small.  Use a size of 0 if not
  679. // using this feature.
  680. //
  681. // Additional representation can be used for "morphing" animations.
  682. // The representation to be visible can be "locked" as the one to
  683. // be drawn at all times, and a sequence of representations used for
  684. // animation.
  685. //  To specify that an object has multiple representations, precede
  686. // the header line of the PLG object with "##MULTI".  Do this for
  687. // all PLG objects to be used as additional representations, except
  688. // the last one.  In other worlds, the first PLG without ##MULTI will
  689. // be the last representation loaded.
  690.  
  691. // This is the simplest function, simply loading the first PLG
  692. // object found in a file.  It can load multiple representations.
  693. // Call add_object_to_world(obj) to place object in the world.
  694.  
  695.     // loads single and multi-rep files
  696.     // will load only one object: call again if not EOF
  697. OBJECT *load_plg_object(FILE *in, POSE *p,
  698.         float sx, float sy, float sz, WORD depth);
  699.  
  700. // This function adds an extra representation to an existing object.
  701. // It can add several representations if ##MULTI is used.  Be sure
  702. // to call physical_update_object(obj) after this so the new representation
  703. // will be properly visible!
  704.  
  705.     // loads a new rep to an old object.
  706.     // useful to create morphing animations
  707.     // just loads FIRST if not multi-rep file
  708.     // Uses <size> parameter to set size field
  709. OBJECT *load_extra_plg_representation(FILE *in, OBJECT *obj, POSE *p,
  710.                     float sx, float sy, float sz, WORD size);
  711.  
  712. // When a complex object consisting of many pieces is loaded, or there
  713. // are many objects in a PLG file to be loaded, it is useful to load
  714. // the objects onto an OBJLIST.  This will allow us to process the
  715. // object(s) as a unit later on.  For example, the objects can be placed into
  716. // the world as a unit, or recolored etc.  A group of simple objects
  717. // may be attached to an invisible "handle" object so they can be moved as a
  718. // unit. Usually, the precreated OBJLIST default_objlist will be used for
  719. // loading and processing objects.
  720.  
  721.     // loads single and multi-rep files
  722.     // will load many objects
  723.     // loads to objlist for later recoloring etc
  724.     // loads as fixed objects so can be joined
  725.     // can limit number to load (so multi objects from file)
  726.     // returns number of objects in list
  727. WORD load_plg_to_objlist(FILE *in, OBJLIST *objlist, WORD maxobj, POSE *p,
  728.              float sx, float sy, float sz, WORD depth);
  729.  
  730. // These functions are used to make loaded, fixed objects moveable.  It
  731. // does this by attaching a SEGMENT (invisible, moveable object) to them.
  732. // The object may then be processed as a unit.
  733.  
  734.     // converts loaded fixed object to moveable
  735.     // adds as visible part to invisible object if supplied
  736.     // if NULL, creates the invisible object part
  737. OBJECT *make_fixed_object_moveable(OBJECT *obj, OBJECT *invis);
  738.  
  739.     // creates moveable object-group from objects in list
  740.     // joins multiple objects to new invisible object
  741.     // which acts as a handle to move the group.
  742. OBJECT *convert_objlist_to_moveable_object(OBJLIST *olist);
  743.  
  744.     // disconnects visible part of object from
  745.     // invisible object, returns visible part.
  746.     // invisible part is stored in **invis.
  747.     // <preserve> sets whether to leave fixed
  748.     // object in same world positon-- DON'T USE
  749.     // if you are going to make object moveable again!
  750. OBJECT *make_moveable_object_fixed(OBJECT *obj, OBJECT **invis, BOOL preserve);
  751.  
  752.  
  753. // Complex jointed object structures are important for animation
  754. // e.g. human figures.  The .FIG file format allows specification of
  755. // figures that can be loaded as a unit, then manipulated.
  756. // Currently, loaded segment files can only be scaled, and are
  757. // placed in position by moving their "handle" or root object.
  758. //
  759. // For animation, it is critical that the various objects in
  760. // the figure be able to be identified.  There are two ways to do
  761. // this.  An object may be named in the .FIG file, and the name
  762. // searched for later with find_seg_by_name(object2segment(obj),"name")
  763. // Or, you can set up a table: OBJECT *segtable[stmax] to hold pointers
  764. // to the objects, that will be filled as the file is read, from "segnum"
  765. // lines in the file.
  766.  
  767.     // load a .FIG file as an object tree
  768.     // resulting tree root is returned
  769.     // objects are not in world and held in objlist
  770.     // "segnum" entries put pointers into <segtable>
  771. OBJECT *load_figure_as_object(FILE *in, OBJLIST *olist, OBJECT **segtable,
  772.                   WORD stmax, float sx, float sy, float sz);
  773.  
  774. // For error reporting, either an error number of a pointer to an
  775. // error message is returned.  These functions are provided:
  776.  
  777.     // load error report from .FIG file load:
  778.     // returns NULL if no error
  779. char *seg_error(SWORD *errnum);
  780.  
  781.     // load error report from .PLG file load:
  782.     // returns NULL if no error
  783. char *plg_error(SWORD *errnum);
  784.  
  785.  
  786.  
  787. /////////////////////////////////////////////////////
  788. ////                                             ////
  789. ////  CREATING OBJECTS FROM SOFTWARE             ////
  790. ////                                             ////
  791. /////////////////////////////////////////////////////
  792.  
  793. // Creating an invisible object (used as part of a motion tree)
  794. // is simple:
  795.  
  796. OBJECT *create_invisible_object();
  797.  
  798. // Creating a visible object is more complex, since the visible
  799. // part of the object must be specified.  YOU MUST NEVER ATTEMPT
  800. // TO ACCESS AN OBJECT REPRESENTATION DIRECTLY, AS IT MAY BE
  801. // STORED IN PAGED EXTENDED MEMORY!  See  EMMSPPT.C for more
  802. // information.
  803. //
  804. // To allocate memory, each representation needs to know the total
  805. // number of polygons, vertices, and polygon vertices.
  806. //
  807. // Creating an object in software requires a series of steps:
  808. //
  809. // -create an object (automatically creates first representation)
  810.  
  811. OBJECT *create_fixed_object(WORD nv, WORD np, WORD npverts);
  812.  
  813. OBJECT *create_moveable_object(WORD nv, WORD np, WORD npverts);
  814.  
  815. // -add all vertex points to the object
  816.  
  817.         // adds vertex to object: these aren't yet hooked to polys
  818. void add_vertex(OBJECT *obj, COORD x, COORD y, COORD z);
  819.  
  820. // -for each polygon:
  821. // --create new polygon
  822.  
  823.         // adds poly to rep: still needs vertex list defined
  824. POLY *add_poly(OBJECT *obj, SURFACE color, WORD npoints);
  825.  
  826. // --add points (polygon vertices, as indexes into vertex table)
  827.  
  828.         // connects vertices to polys thru vertex lists
  829. void add_point(OBJECT *obj, POLY *p, WORD vertindex);
  830.  
  831. //
  832. // -for every additional representation, create it, then
  833. //  repeat the last 4 steps
  834.  
  835. REP *add_representation(OBJECT *obj, WORD size, WORD nv, WORD np, WORD tpverts);
  836.  
  837. // After creating the object, you must compute cached data for the
  838. // object: its bounding sphere, and each of it's polygon's normals.
  839. // Use these functions after creating an object:
  840.  
  841. // The compute_object() functions are OK if the object will
  842. // be placed into or moved within the world immediately.
  843.  
  844. // Use this for each or last-added representation:
  845.  
  846.       // computes renderer data for object
  847.       // for current rep only!
  848. void compute_object(OBJECT *obj);
  849.  
  850. // Use this if you've added more than one rep to an object
  851.  
  852.       // computes renderer data for object
  853.       // for all representations
  854. void compute_all_object(OBJECT *obj);
  855.  
  856. // this also takes care of wolrd and location updates
  857. // caused by changing an object, and is safer.
  858.  
  859.     // recomputes object normals, bounding sphere
  860.     // and if moved: current representation only
  861. void physical_update_object(OBJECT *obj);
  862.  
  863. // If speed is no problem, global_update_object is safest.
  864.  
  865.     // massive update: recomputes all object's reps,
  866.     // forces all connecting objects to update position
  867. void global_update_object(OBJECT *obj);
  868.  
  869.  
  870. /////////////////////////////////////////////////////
  871. ////                                             ////
  872. ////  OBJECT SUPPORT: REPRESENTATION CONTROL     ////
  873. ////                                             ////
  874. /////////////////////////////////////////////////////
  875.  
  876. // Some objects may have multiple representations.  A representation
  877. // (REP) is the descripton of the visible part of an object, and
  878. // consists of its polys, colors, and vertices.
  879. // Multiple representations are usually used to increase rendering speed,
  880. // by letting distant (small) objects disappear or be drawn in a simpler
  881. // form than when close and large.  The size in pixels that the object
  882. // must subtend on the screen to be visible is set by the "size"
  883. // parameter, which may be set in the PLG file in the object name.
  884. // A representation of size 0 will always be seen, while larger "size"
  885. // representations can disappear if too small.  Use a size of 0 if not
  886. // using this feature.
  887. //
  888. // Additional representation can be used for "morphing" animations.
  889. // The representation to be visible can be "locked" as the one to
  890. // be drawn at all times, and a sequence of representations used for
  891. // animation.
  892. //
  893. // In some cases, access to a specific representation
  894. // is required.  The representations on an object are
  895. // in a list, with "largest" <size field> first.
  896. // Representation of the same size are stored last-first.
  897. // One of the representations will be "current" at any time,
  898. // and is the only one that may be manipulated.
  899.  
  900.      // make first rep the current one: used during lock
  901. void select_first_representation(OBJECT *obj);
  902.  
  903.     // make next rep the current one: used during lock
  904.     /* return 1 if wrapping back to first */
  905. WORD select_next_representation(OBJECT *obj);
  906.  
  907.     // find representation that will be
  908.     // active at given screen size
  909. void select_representation(OBJECT *obj, WORD size);
  910.  
  911. // These functions are the heart of morphing animations.
  912.  
  913.     // forces renderer to always draw rep
  914.     // if n = 0, it will be the current rep
  915.     // Otherwise, it's the Nth representation
  916. void lock_current_representation(OBJECT *o, WORD n);
  917.  
  918.     // goes back to select-by-size mode
  919. void unlock_current_representation(OBJECT *o);
  920.  
  921. // Sometimes, you need to change the size field of a representation
  922.  
  923.                 // set size field of rep
  924. void set_representation_size(OBJECT *obj, WORD size);
  925.  
  926.                 // read size field
  927. WORD get_representation_size(OBJECT *obj);
  928.  
  929.  
  930. /////////////////////////////////////////////////////
  931. ////                                             ////
  932. ////  OBJECT SUPPORT: CHANGING COLOR AND SURFACE ////
  933. ////                                             ////
  934. /////////////////////////////////////////////////////
  935.  
  936. // VR-386 is flexible enough to use many methods of coding
  937. // colors and surface types (see COLORMAP.C for details
  938. // of the current hue/reflectance method, similar to that
  939. // used by REND386).
  940. // You should use SURFACE as the type for all color/surface specifiers,
  941. // to improve compatibility with future upgrades, since 32-bit or
  942. // pointers may be needed for RGB colors or texture mapping in the future.
  943. //
  944. // There are two recoloring methods used: one is a global "change everything"
  945. // strategy, and the other can change sets of colors to other colors
  946. // selectively.  This last uses an array of SURFACEPAIRS, as:
  947. //
  948. // typedef struct  {               // pair for surface remapping
  949. //               SURFACE old;
  950. //          SURFACE new;
  951. //           } SURFACEPAIR;
  952. //
  953. //  The matching and replacement of bits in the process are controlled
  954. // by masks, making it easy to change only the hue field of the
  955. // surface description, or to select a polygon for recoloring by the
  956. // 3 LSB of its brightness field.  These bits can be preserved by
  957. // the write mask.
  958.  
  959. // This function modifies all polygons in an object.  Where bits in
  960. // <bitmask> are set, bits from <new> replace current surface bits
  961. // in the polygon.  The <all> flag, if set, processes ALL representations
  962. // of the object, otherwise only the current representation is processed.
  963.  
  964.     // flexible recolor/resurface object
  965. void masked_recolor_object_surface(OBJECT *obj, SURFACE new,
  966.                     SURFACE bitmask, BOOL all);
  967.  
  968. // This function modifies only polygons whose current surface matches
  969. // one of the SURFACEPAIR.old in <map>.  Only bits where <sbitmask>'s bits
  970. // are set are used in the comparison. Only the set bits in <dbitmask>
  971. // from the pair's .new field will replace current surface bits
  972. // in the polygon.  The <all> flag, if set, processes ALL representations
  973. // of the object, otherwise only the current representation is processed.
  974.  
  975.     // very flexible remaps colors of object
  976. void masked_remap_object_surface(OBJECT *obj, SURFACEPAIR map[20], WORD nmap,
  977.               SURFACE sbitmask, SURFACE dbitmask, BOOL all);
  978.  
  979. #define MAP_ALL_MASK          0xFFFF   // some useful masks
  980. #define IGNORE_HIGHLIGHT_MASK 0x7FFF
  981. #define MAP_SURFACE_MASK      0x3000   // test/modify surface type only
  982. #define MAP_HUE_MASK          0x0F00   // test/modify hue only
  983. #define MAP_BRIGHTNESS_MASK   0x00FF   // test/modify brightness only
  984. #define MAP_PALETTE_MASK      0x00FF   // test/modify abs. 256 color palette entry
  985.  
  986. #define TEST_B3BITS_MASK      0x0007   // test 3 LSB as "type" code
  987. #define KEEP_B3BITS_MASK      0xFFF8   // keep the 3 LSB as "type" code
  988.  
  989. // When loading objects, we want to be able to process all the objects
  990. // and their representations immediately.  The objects are in an
  991. // OBJLIST, and it is most convenient to use this function when loading
  992. // objects:
  993.  
  994.     // very flexible remaps colors
  995.     // does for all objects in objlist
  996. void objlist_remap_surface(OBJLIST *olist, SURFACEPAIR map[20], WORD nmaps,
  997.               SURFACE sbitmask, SURFACE dbitmask);
  998.  
  999. // The standard PLG remapping used in REND386 used 0x80xx as the "raw"
  1000. // color number, with "xx" being the number in the surfacemap.  It is
  1001. // trivial to set up a SURFACEPAIR table to do this replacement: set the
  1002. // MSB of the .old color numbers, and the .new is the desired surface.
  1003. // Use MAP_ALL_MAP for <sbitmask> and <dbitmask>.
  1004.  
  1005.  
  1006. // For direct color access into polygons, these low-level functions
  1007. // are supplied:
  1008.  
  1009.     // get data on poly
  1010.     // use poly number ito object
  1011.     // use NULL for *color and *nverts
  1012.     // if you don't want their data
  1013. void get_poly_info(OBJECT *obj, WORD polynum, SURFACE *color, WORD *nverts);
  1014.  
  1015.     // set poly's color number
  1016. void set_poly_color(OBJECT *obj, WORD polynum, SURFACE color);
  1017.  
  1018.  
  1019. /////////////////////////////////////////////////////
  1020. ////                                             ////
  1021. ////  OBJECT SUPPORT: DELETIONS                  ////
  1022. ////                                             ////
  1023. /////////////////////////////////////////////////////
  1024.  
  1025. // In most cases, objects are not deleted individually.
  1026. // Usually an entire movement tree, OBJLIST or world
  1027. // visiblilty tree is deleted at once.  More deletions
  1028. // support will be available when world deletion is complete.
  1029.  
  1030.  
  1031. // This function deltes the visible part of a moveable
  1032. // object, or a fixed object entirely.  It is best used
  1033. // for deletions when you're not sure if the segment
  1034. // of the object is in use elsewhere.
  1035.  
  1036.     // deletes fixed object or
  1037.     // visible part of moveable object
  1038.     // also removes from any objlist
  1039. void delete_visobj(OBJECT *obj);
  1040.  
  1041. // This function deletes invisible, visible or moveable
  1042. // objects.  It cannot delete objects that are registered
  1043. // as system-owned, such as the segments of cameras or lights.
  1044. // Delete these with delete_light() or delete_camera()
  1045.  
  1046.     // can delete segments or visobjs, but not if
  1047.     // the segment is system owned (camera, light)
  1048.     // also removes from any objlist
  1049. void delete_object(OBJECT *obj);
  1050.  
  1051. // object list deletions:
  1052.  
  1053.     // delete objects on list then delete objlist
  1054. void delete_objlist_and_objects(OBJLIST *list);
  1055.  
  1056.     // delete objlist, but just remove objects from list
  1057.     // safer if not sure all objects are off list
  1058. void delete_objlist_keeping_objects(OBJLIST *list);
  1059.  
  1060. // You may also want to delete the objects in the tree
  1061. // completely.  This can be done for the children of the
  1062. // object, or for the entire tree if find_root_object(obj) is
  1063. // used.
  1064.  
  1065.     // delete object, and descendent objects
  1066.     // both moveable and invisinble objects deleted
  1067. void delete_object_and_children(OBJECT *obj);
  1068.  
  1069.  
  1070. /////////////////////////////////////////////////////
  1071. ////                                             ////
  1072. ////  OBJECT SUPPORT: MISCELLANEAOUS             ////
  1073. ////                                             ////
  1074. /////////////////////////////////////////////////////
  1075.  
  1076. // Every visible object has a bounding sphere.  This function
  1077. // reports the world position of its center and its radius.
  1078.  
  1079. COORD get_object_bounds(OBJECT *obj, COORD *x, COORD *y, COORD *z);
  1080.  
  1081.     // get data on poly of object
  1082. void get_poly_info(OBJECT *obj, WORD polynum, SURFACE *color, WORD *nverts);
  1083.  
  1084.     // set surface type of object poly
  1085. void set_poly_color(OBJECT *obj, WORD polynum, SURFACE color);
  1086.  
  1087.     // gets number of vertices, polys for current rep
  1088. void get_obj_info(OBJECT *obj, int *nv, int *np);
  1089.  
  1090.     // sum of number of vertices of all polys for current rep
  1091. WORD total_object_pverts(OBJECT *obj);
  1092.  
  1093.     // get/set object dorting type (see LOADING...)
  1094. WORD get_object_sorting(OBJECT *obj);
  1095. void set_object_sorting(OBJECT *obj, WORD depth_type);
  1096.  
  1097. // vertices are referenced in two ways: as an entry in the object's
  1098. // vertex table, and as the vertex number of a polygon.
  1099. // This fuctions converts a polygon's vertex number (0..n-1)
  1100. // to the index in the vertex table.
  1101.  
  1102. WORD get_poly_vertex_index(OBJECT *obj, WORD poly, WORD vertex);
  1103.  
  1104. // To actually modify the shape of an object, it is only really
  1105. // feasible to move the vertices.  These functions will allow
  1106. // the object's internal vertex coords to be accessed and modified.
  1107. // Don't forget to call physical_object_update() after changing
  1108. // the object.
  1109.  
  1110. void get_vertex_info(OBJECT *obj, WORD vertnum, COORD *x, COORD *y, COORD *z);
  1111. void set_vertex_coords(OBJECT *obj, int vertnum, COORD x, COORD y, COORD z);
  1112.  
  1113. // This function scales the size of an object.  You must call
  1114. // physical _update_object afterwards.  Not useful with small objects,
  1115. // and precision is lost after each scaling.  Mostly useful for
  1116. // setting up objects.
  1117.  
  1118. void scale_object(OBJECT *obj, float sx, float sy, float sz);
  1119.  
  1120. // When an existing object must be moved or rotated internally,
  1121. // (NOT in the usual way), then its internal representation
  1122. // must be changed.  Precision will be lost, of course.  But
  1123. // the best way to do this is to use a homogenous matrix to
  1124. // move the world position of the object, then to copy the
  1125. // world vertex positions into the "object" vertex information.
  1126. // The matrix may be derived from a segment, or may be generated by
  1127. // one of the routines in the INTMATH library.
  1128.  
  1129. void apply_matrix(OBJECT *obj, MATRIX m);  // moves object completely
  1130. void copy_world_to_object(OBJECT *obj);  // used to "lock" fixed objects
  1131.  
  1132. // Once a visible object has been rendered, the world coordinates
  1133. // for each of its vertices is cached internally.  This routine
  1134. // can extract that information for use in collision detection
  1135. // or other routines.
  1136.  
  1137. void get_vertex_world_info(OBJECT *obj, WORD vertnum, COORD *x, COORD *y, COORD *z);
  1138.  
  1139. // This function scans an OBJLIST, looking for the object whose center
  1140. // closest to the given world point.  It only chacks objects whose
  1141. // bounding sphere includes the point of interest.  Usually it is used in
  1142. // combination with world areas (see MANIP3D.C for an example).
  1143.  
  1144.     // determines closest object in list
  1145. OBJECT *best_collision(OBJLIST *objlist, COORD x, COORD y, COORD z);
  1146.  
  1147. // At oresent, there are NO user-manipulable flags in the
  1148. // objects.  There may be a user flag word in the future.
  1149.  
  1150. void set_obj_flags(OBJECT *obj, WORD val);
  1151.  
  1152. WORD get_obj_flags(OBJECT *obj);
  1153.  
  1154.       // set/clear flags in visobj part of object
  1155. void set_object_flags(OBJECT *obj, WORD flagmask, WORD bitval);
  1156.  
  1157. // For completeness, the object-update functions are listed here:
  1158.  
  1159.     // recomputes object normals, bounding sphere
  1160.     // and if moved: current representation only
  1161. void physical_update_object(OBJECT *obj);
  1162.  
  1163.     // massive update: recomputes all object's reps,
  1164.     // forces all connecting objects to update position
  1165. void global_update_object(OBJECT *obj);
  1166.  
  1167.     // converts loaded fixed object to moveable
  1168.     // adds as visible part to invisible object if supplied
  1169. OBJECT *make_fixed_object_moveable(OBJECT *obj, OBJECT *invis);
  1170.  
  1171.     // creates moveable object-group from objects in list
  1172.     // joins multiple objects to new object
  1173. OBJECT *convert_objlist_to_moveable_object(OBJLIST *olist);
  1174.  
  1175.  
  1176. /////////////////////////////////////////////////////
  1177. ////                                             ////
  1178. ////  CAMERAS, STEREOSCOPIC SUPPORT (SCAMERA.C)  ////
  1179. ////                                             ////
  1180. /////////////////////////////////////////////////////
  1181.  
  1182. // A CAMERA is a device for reproducing a monoscopic
  1183. // or stereoscopic view of the world to the screen.
  1184. // The camera may be moved like any object, or
  1185. // attached to any object.  A special CAMERA,
  1186. // default_camera, is created and set up during
  1187. // configuration to use as a template (in many programs,
  1188. // this may be the only camera used). Usually the default camera is
  1189. // attached to the "body" object's "head" object
  1190. // for use with head trackers and HMDs
  1191.  
  1192. // The default_camera is created at initialization, and is modified
  1193. // during configuration.  The current_camera will be used for
  1194. // rendering and view-dependant calculations.
  1195.  
  1196. extern CAMERA * default_camera;      // the "basis" camara for world
  1197. extern CAMERA * current_camera;   // the current camera used for rendering
  1198.  
  1199.     // creates, initializes camera
  1200.     // may be stereo or mono, may copy another camera
  1201. CAMERA *create_camera(BOOL is_stereo, CAMERA *template);
  1202.  
  1203.     // delete camera, free memory
  1204. void destroy_camera(CAMERA *c);
  1205.  
  1206. //  These commect and disconnect the camera from objects that
  1207. // can move the camera in the world:
  1208.  
  1209.     // attach camera to moveable object
  1210. void attach_camera(CAMERA *c, OBJECT *obj);
  1211.  
  1212.     // detach camera
  1213. void detach_camera(CAMERA *c);
  1214.  
  1215. // These functions manipulate camera pose.  Recall that
  1216. // local and world pose are the same if the camera is
  1217. // not attached to anything: the default_camera is
  1218. // always attached to body_seg, so the local pose is the head-to-body
  1219. // angle of the head tracker, and the world pose is the "real"
  1220. // viewpoint and look angle.
  1221.  
  1222.     // set camera pose (if attached, set relationship)
  1223. void set_camera_pose(CAMERA *c, POSE *p);
  1224.  
  1225.     // get pose with relation to object attached to
  1226. void get_camera_localpose(CAMERA *c, POSE *p);
  1227.  
  1228.     // get world position/angle
  1229. void get_camera_worldpose(CAMERA *c, POSE *p);
  1230.  
  1231. // Certain operations must be done with respect to the camera's view
  1232. // itself.  For example, mouse and 3D pointer operations must
  1233. // take place in the camera's view coordinates so that motion in
  1234. // the world and on the screen always match.  When loading PLG
  1235. // files, we want to place the object "ahead" of the camera so it
  1236. // appears a constant size... and so on.
  1237.  
  1238.     // get the MONOSCOPIC camera pose matrix
  1239.     // usually best match for stereoscopic cameras as well
  1240. void get_camera_matrix(CAMERA *c, MATRIX m);
  1241.  
  1242.     // computes coords of point in fromnt of MONOSCOPIC camera
  1243. void camera_point_ahead(CAMERA *c, COORD distance,
  1244.             COORD *xp, COORD *yp, COORD *zp);
  1245.  
  1246. // This is used during rendering to extract a VIEW (window description)
  1247. // from the camera, and set up the renderer to use it.
  1248.  
  1249.     // sets renderer to draw a view, mono or stereo view
  1250.     // also computes camera position from object it
  1251.     // is attached to
  1252. VIEW *select_camera_view(CAMERA *c, WORD which_eye);
  1253.  
  1254. // CAMERA view factors for stereoscopic and monoscopic views are
  1255. // set differently.  There are many support functions for mono
  1256. // cameras, as almost any parameters make sense.  For stereo,
  1257. // there are too many interrelated factors.  Most stereo
  1258. // factors are best set up with the STEREO data structure:
  1259. // default_stereo is set up during configuration.
  1260. //
  1261. // After any parameters are changed (except camera position),
  1262. // the camera must be recomputed to cache internal coefficients:
  1263.  
  1264.     // computes the static stereo factors for camera, caches
  1265. void compute_camera_factors(CAMERA *c);
  1266.  
  1267. // Camera hither and yon clipping can be set in both stereo and
  1268. // mono cameras simultaneously:
  1269.  
  1270.     // set/get  hither clipping
  1271. void set_camera_hither(CAMERA *c, COORD h);
  1272. COORD get_camera_hither(CAMERA *c);
  1273.  
  1274.     // set/get yon clipping
  1275. void set_camera_yon(CAMERA *c, COORD y);
  1276. COORD get_camera_yon(CAMERA *c);
  1277.  
  1278. // These set monoscopic "zoom" (field of view). FOV is
  1279. // equal to 2*atan(1/zoom)
  1280.  
  1281.     // set the MONOSCOPIC zoom
  1282. void set_camera_zoom(CAMERA *c, SCALE zoom);
  1283.  
  1284.     // get the MONOSCOPIC zoom
  1285. SCALE get_camera_zoom(CAMERA *c);
  1286.  
  1287. // For stereoscopic "zoom", there is no function to set
  1288. // zoom, because many stereoscopic parameters to be changed to
  1289. // get good stereo.  Instead, adjust:
  1290. //    get_camera_stereo(CAMERA)->phys_screen_dist
  1291. //
  1292. // the equivalent zoom is (right-left)/2/distance
  1293.  
  1294.  
  1295.     // set the MONOSCOPIC view window on screen
  1296. void set_camera_window(CAMERA *c, WORD l, WORD t, WORD r, WORD b);
  1297.  
  1298. // For stereoscopic cameras, the window must be set through
  1299. // the two windows in the camera's STEREO: example: left side:
  1300. //    get_camera_stereo(CAMERA)->window[LEFT_EYE].l
  1301. //    get_camera_stereo(CAMERA)->window[RIGHT_EYE].l
  1302.  
  1303. // As noted, the STEREO structure controls stereo camera image generation.
  1304. // These functions allow you to create cameras with parameters
  1305. // different from those set into default_stereo during configuration:
  1306.  
  1307.     // this pre-initialized STEREO controls the default camera
  1308.     // usually shared by all cameras
  1309. extern STEREO default_stereo;
  1310.  
  1311.     // make a unique (nonshared) stereo
  1312.     // parameter structure for camera
  1313. STEREO *create_new_stereo(CAMERA *c, CAMERA *template);
  1314.  
  1315.     // pointer to camera's stereo parameter structure
  1316. STEREO *get_camera_stereo(CAMERA *c);
  1317.  
  1318.     // makes camera use stereo parameter structure
  1319. STEREO *set_camera_stereo(CAMERA *c, STEREO *s);
  1320.  
  1321.  
  1322. /////////////////////////////////////////////////////
  1323. ////                                             ////
  1324. ////  LIGHTS: POINT, DIRECTIONAL AND AMBIENT     ////
  1325. ////  (LIGHTS.C) and (COLORMAP.C)                ////
  1326. ////                                             ////
  1327. /////////////////////////////////////////////////////
  1328.  
  1329. // LIGHTS may be treated as object: moved, rotated and attached
  1330. // to other objects.  Arrays of (LIGHT *) may be used to
  1331. // light scenes, and can be used very flexibly.  There are
  1332. // 3 types of lights:
  1333. //
  1334. // AMBIENT_LIGHT lights all polys the same
  1335. //
  1336. // SPOT_LIGHT lights all polys from the same side,
  1337. // determined by the rotation of the light: zero angle
  1338. // lights from the +Z side
  1339. //
  1340. // POINT_LIGHT lights polys from a point in space, set by
  1341. // the position of the light only.
  1342. //
  1343. // It is up to COLORMAP.C to decide how to cope with light data:
  1344. // in the basic version, the total of all lights is scaled
  1345. // to a constant 127 for integer calculations.  See WPARSE.C
  1346. // to see code for creating default lights, and USERVID.c
  1347. // and COLORMAP.C for a sample lighting system.
  1348.  
  1349.     // create, initialize a light and its segment
  1350. LIGHT *create_light(OBJECT *parent, WORD type, WORD intensity);
  1351.  
  1352.     // destroy a light and its segment
  1353.     // light and camera segments can only
  1354.     // be deleted through their delete functions
  1355. void destroy_light(LIGHT *l);
  1356.  
  1357.     // returns light type
  1358. WORD get_light_type(LIGHT *l);
  1359.  
  1360.     // returns light intensity
  1361. WORD get_light_intensity(LIGHT *l);
  1362.  
  1363.     // sets intensity of light
  1364. void set_light_intensity(LIGHT *l, WORD i);
  1365.  
  1366.     // sets light type
  1367. void set_light_type(LIGHT *l, WORD t);
  1368.  
  1369.     // attaches light to an object
  1370.     // option to preserve world location
  1371.     // (see attach_object() for info on this option)
  1372. BOOL attach_light(LIGHT *l, OBJECT *obj, BOOL preserve);
  1373.  
  1374.     // detaches light from object
  1375.     // option to preserve world location
  1376. BOOL detach_light(LIGHT *l, BOOL preserve);
  1377.  
  1378.     // change angle of a spotlight
  1379.     // (forces light to be spotlight)
  1380. BOOL rotate_spotlight(LIGHT *l, POSE *p);
  1381.  
  1382.     // change position of point source
  1383.     // (forces light to be point source)
  1384. BOOL position_pointlight(LIGHT *l, POSE *p);
  1385.  
  1386.     // change pos/rot of light source
  1387.     // Makes it possible to have both point
  1388.     // and spotlight data for light
  1389. BOOL set_light_pose(LIGHT *l, POSE *p);
  1390.  
  1391.     // get local (joint) position/angle of light
  1392. void get_light_localpose(LIGHT *l, POSE *p);
  1393.  
  1394.     // get world position/angle of light
  1395. void get_light_worldpose(LIGHT *l, POSE *p);
  1396.  
  1397.  
  1398. // To actually USE the lights we've created, we must
  1399. // pass an array of (LIGHT *) to this routine which
  1400. // MUST be supplied by YOU.  There is a sample in COLORMAP.C
  1401.  
  1402.     // usually in COLORMAP.C, sets up lights to renderer
  1403. void setup_lights(LIGHT *llist[], WORD nlights);
  1404.  
  1405.     //  fetch light data for computing
  1406.     // lighting data in COLORMAP.C
  1407. WORD get_light_data(LIGHT *l, COORD *xp,
  1408.             COORD *yp, COORD *zp, WORD *intensity);
  1409.  
  1410.  
  1411.  
  1412. /////////////////////////////////////////////////////
  1413. ////                                             ////
  1414. ////   USER INTERFACE SUPPORT                    ////
  1415. ////                                             ////
  1416. /////////////////////////////////////////////////////
  1417.  
  1418. // VR-386 has many tools for user interfaces.  These support:
  1419. //
  1420. // -keyboard responses and control
  1421. // -mouse for object selection and manipulation
  1422. // -"joystick" type navigation via keyboard, mouse, joystick
  1423. // -popup message boxes and menus on screen
  1424. // -PowerGlove and 3d/6d pointing device interfaces
  1425. // -support for head tracking devices.
  1426. //
  1427. // These devices are rather basic; a standardized "pointer"
  1428. // interface system makes development and adding of device
  1429. // drivers easier.  Pointers will be discussed elsewhere in
  1430. // more detail, but basically consist of a simple device driver,
  1431. // (PDRIVER) which can initialize, reset, read, and control
  1432. // the device.  Much of the functionality of a normal device
  1433. // driver is taken over by the VR-386 pointer system, such as
  1434. // scaling and motion detection.  A data block describing the
  1435. // device (PCONFIG) contains information of the driver's resolution,
  1436. // range and so on.
  1437. // Pointers support two basic modes: pointer and mouse.  The idea
  1438. // is to let any device funstion both as a pointing device
  1439. // (2D, 3D, etc) and as a 2D mouse, scaled to the screen, for
  1440. // use in object selection and menu selection.
  1441. //
  1442. //  Many of the keyboard functions in this release are in
  1443. // KEYBOARD.C, which is a large key and menu support interperter.
  1444. // If you need to see how any VR-386 editing feature is implemented,
  1445. // look there first.  You can easily remove the KEYBOARD.C from the link,
  1446. // as very few functions in it are critical.  Only a few functions
  1447. // are really needed, mostly Quit and the basic key processing for
  1448. // motion control.  This module basically is written to be compatible
  1449. // with REND386 release 5.
  1450.  
  1451.  
  1452. /////////////////////////////////////////////////////
  1453. ////                                             ////
  1454. ////   USER INTERFACE SUPPORT: MOUSE, CURSOR     ////
  1455. ////                                             ////
  1456. /////////////////////////////////////////////////////
  1457.  
  1458. // VR-386 uses the mouse to move a 2D cursor, or to
  1459. // manipulate objects (the mouse-navigation is discussed
  1460. // later).  Mouse functions can be split into cursor-related
  1461. // and menu-related, each driven by a different pointer device:
  1462. // cursor_device and menu_device.  These are usually the same.
  1463. // Cursor drawing is implemented by the video driver.
  1464. // (Future drivers may support multiple types of bitmap cursors).
  1465. //
  1466. //  Before drawingto the screen, the cursor must be hidden,
  1467. // then shown after drawing.  cursor_hide() returns a flag that
  1468. // can be saved to determine if the cursor will need to be
  1469. // redrawn later.
  1470.  
  1471. // If the cursor is not to be seen (mouse is not available) the
  1472. // cursor drawing may be turned off: cursor_show is ignored.
  1473.  
  1474. extern void cursor_enable(BOOL state);   /* hardwire on/off */
  1475.  
  1476. // The basic cursor operations are to hide and redisplay it.
  1477. // Flags are used to ensure that a cursor is not erased or drawn
  1478. // twice, as this will leave garbage on the screen.
  1479. // All cursor operations are performed to the current_video_page,
  1480. // set by the screen refresh to be the same as the displayed video page.
  1481.  
  1482. extern BOOL cursor_hide(void);      /* erase cursor, rtn visible flag */
  1483. extern void cursor_show(void);      /* redisplay cursor */
  1484.  
  1485. // During rendering, drawing is done to a different video page,
  1486. // and the cursor is erased from the old page and drawn to the
  1487. // new current page after the screen refresh is done.  Thus
  1488. // a function to specify which page the cursor is to be erased
  1489. // from is needed.
  1490.  
  1491. extern BOOL last_cursor_hide(WORD page);  /* erase cursor, on specific page */
  1492.  
  1493. // Combining hide and redraw  at a new position moves the
  1494. // cursor on the screen:
  1495.  
  1496. extern void cursor_move(WORD x, WORD y);   /* move cursor if visible */
  1497.  
  1498. // Integrating mouse reading and cursor motion into one
  1499. // function.  This reads the mouse once, moves the cursor and returns.
  1500. // <d> is a pointer to a mouse driver (usually cursor_device),
  1501. // and *x, *y, and *b will be filled with current mouse position and
  1502. // button status: b&0x01 for left button, and b&0x02 for right.
  1503.  
  1504. extern WORD move_2D(PDRIVER *d, WORD *x, WORD *y, WORD *b);
  1505.  
  1506. // Adding a loop to move the mouse till a click is detected:
  1507. // Unlike move_2D(), <b> is a mask for which buttons are to
  1508. // be tested: 1 for left, 2 for right, 3 for both.  The button
  1509. // clicked is returned (same code).
  1510.  
  1511. extern WORD move_till_click(PDRIVER *d, WORD b, WORD *x, WORD *y);
  1512.  
  1513. //  Often a function needs to see if the mouse is available.  This returns
  1514. // Returns 1 if true, else pops up warning message.
  1515.  
  1516. extern BOOL can_point_2D(void);
  1517.  
  1518.  
  1519. /////////////////////////////////////////////////////
  1520. ////                                             ////
  1521. ////   MOUSE AND SCREEN SELECTION OF OBJECTS     ////
  1522. ////                                             ////
  1523. /////////////////////////////////////////////////////
  1524.  
  1525. // A critical feature of VR-386 is its ability to select
  1526. // objects by simply clicking on their image on the screen.
  1527. // The screen-to-object system can also find which polygon
  1528. // and (if possible) vertex of the object was clicked on,
  1529. // and is based on the screen-monitor built into the renderer.
  1530.  
  1531. // this function reports the object which is visible at
  1532. // that point on the screen.  This is done by enabling the
  1533. // screen monitor, refreshing the screen, then recording
  1534. // the results.  Returns NULL if no object found.
  1535.  
  1536. OBJECT *find_object_on_screen(WORD x, WORD y);
  1537.  
  1538. // this is called internally by find_object_on_screen to
  1539. // process the screen monitor output:
  1540.  
  1541. void process_screen_monitor();
  1542.  
  1543. // The results may be read by calling these functions.  The
  1544. // poly and vertex indices are -1 if no object, poly, or
  1545. // vertex was found.  It is possible to find an object but
  1546. // not to find a vertex.
  1547.  
  1548. OBJECT *screen_found_object();        // object (NULL if none)
  1549. SWORD screen_found_poly();        // poly index in object
  1550. SWORD screen_found_poly_vertex();    // which vertex in poly (order)
  1551. SWORD screen_found_object_vertex();    // which vertex in object (table)
  1552.  
  1553. // This function will read the mouse once, move the cursor,
  1554. // and check if it was clicked.  If so, it checks to see
  1555. // which object was clicked on.  <*buttons> will contain
  1556. // the button state, and NULL will be returned if no
  1557. // button was clicked.  This function should be called in a loop.
  1558.  
  1559. OBJECT *move_and_find_object_2D(PDRIVER *d, WORD *buttons);
  1560.  
  1561. // This function implements the core of the "screen idle" call
  1562. // It reads the mouse once, moves the cursor, and checks for
  1563. // a button click (left button only).  Returns 0 if no click
  1564. // or click in inactive area, -1 if menu-area click (top of screen)
  1565. // or 1 if new object selected/deselected.
  1566. // INSTALL EXTRA SCREEN-CLICK HANDLERS HERE.
  1567.  
  1568. SWORD move_and_select_2D(PDRIVER *d);
  1569.  
  1570. // THis is the main mouse-processing call for the VR-386 run loop.
  1571. // It processes menu mouse clicks as well.
  1572.  
  1573. extern void mouse_process();
  1574.  
  1575.  
  1576. /////////////////////////////////////////////////////
  1577. ////                                             ////
  1578. ////   SCREEN INTERFACE SUPPORT: DIALOGS, MENUS  ////
  1579. ////                                             ////
  1580. /////////////////////////////////////////////////////
  1581.  
  1582.  
  1583.     // reads keyboard, checks for CTRL-F10 (screen dump)
  1584.     // Encodes left/right shifts, ALT and CTRL keys
  1585.     // as modifiers on all keys.  See USERINT.H for
  1586.     // key codes.
  1587. WORD getkey(void);
  1588.  
  1589.     // saves screen to old video page
  1590.     // only done for first call after rendering
  1591. void save_screen();
  1592.  
  1593.     // restores screen as saved by save_screen();
  1594.     // used to erase menus, text boxes, etc.
  1595. void restore_screen();
  1596.  
  1597.     // prints box for text, centered on screen
  1598.     // with width <w> and height <h>
  1599. void neatbox(int w, int h, int *x, int *y);
  1600.  
  1601.     // print a text box containing several lines (37 char MAX)
  1602.     // in the center of screen.  Last entry of array must be NULL
  1603. void poptext(char *text[]);
  1604.  
  1605.     // print a text box containing one line (37 char MAX)
  1606.     // at center of screen
  1607. void popmsg(char *msg);
  1608.  
  1609.     // prints to "popmsg" box
  1610.     // useful for debugging
  1611.     // prints to stderr if not in graphics mode
  1612. WORD popprintf(char *fmt, ...);
  1613.  
  1614.     // This is a way to get text response from user.
  1615.     // A prompt is printed, and up to <n> characters
  1616.     // are accepted.  Prompt and <n> should be less than
  1617.     // 36 characters.  Backspace is supported.  ESC
  1618.     // will exit with an empty buffer: buff[0]==0
  1619.     // Returns exit character.
  1620. WORD askfor(char *prompt, char *buff, WORD n);
  1621.  
  1622.     // test for response event, used to terminate waits,
  1623.     // abort loops, and so on.  A joystick or mouse
  1624.     // click is accepted as a response as well as a keypress.
  1625.     // returns 0 if no response, buttons (1,2,3) for mouse,
  1626.     // 4 if joystick click, else key value
  1627.     // if <wait>, then the function will not return till
  1628.     // a response is given.
  1629. WORD get_response(BOOL wait);
  1630.  
  1631.     // prints out menu (a NULL-terminated array of char *)
  1632.     // at center of screen.  Responses should correspond to
  1633.     // the first capitalized letter in each line, which is
  1634.     // returned if the line is clicked on by mouse.
  1635.     // A click outside the menu or by joystick, or ESC exits
  1636.     // returns 0 or the capitalized letter of the selected entry.
  1637. WORD menu(char *text[]);
  1638.  
  1639.  
  1640. /////////////////////////////////////////////////////
  1641. ////                                             ////
  1642. ////       KEY PROCESSING                           ////
  1643. ////                                             ////
  1644. /////////////////////////////////////////////////////
  1645.  
  1646. // The key process routines must process key
  1647. // preses, passing certain ones on to be used
  1648. // for moving the user, and ignoring the key presses
  1649. // that are intercepted by the key monitor.  The method
  1650. // suggested is to have a series of key processing
  1651. // routines, as in KEYBOARD.C, that look for keys they
  1652. // can handle, returning TRUE if they have processed the key.
  1653.  
  1654. // The routines should be:
  1655.  
  1656.     // processes key <c>, calling sequence of key handlers
  1657.     // until one returns TRUE to mark key as processed
  1658. void process_a_key(unsigned c);
  1659.  
  1660.     // calls getkey() to read a key, calls
  1661.     // process_a_key to handle it
  1662.     // should get first key in queue, dump others
  1663.     // to prevent type-ahead
  1664. void key_process();
  1665.  
  1666. // Look at the end of KEYBOARD.C for sample routines.
  1667.  
  1668.  
  1669.  
  1670. /////////////////////////////////////////////////////
  1671. ////                                             ////
  1672. ////       SCREEN REFRESH ROUTINES                  ////
  1673. ////                                             ////
  1674. /////////////////////////////////////////////////////
  1675.  
  1676. // Screen refresh is supported by the video driver,
  1677. // the renderer kernal, as well as a variety of user-
  1678. // customizable routines.  The refresh is designed to support
  1679. // monoscopic as well as several types of stereoscopic
  1680. // views: switched (left-right alternate frames displayed),
  1681. // windowed (seperate left and right windows on screen,
  1682. // and seperate viddeo displays for left and right eye
  1683. // views.
  1684. // User customizable routines in USERVID.C are used to perform the
  1685. // basic drawing tasks, such as lines, polygons, text,
  1686. // and screen clearing.  These provide alternates to the
  1687. // standard video driver interface.  THe polygon drawing
  1688. // routine, in combination with the color-coding routines
  1689. // in COLORMAP.C, allow for almost any lighting and color
  1690. // system to be supported.
  1691. //
  1692. // Screen refresh proceeds in stages.  First, the video page
  1693. // to be drawn is selected.  The rendering areas are then
  1694. // prepared with a call to prerender_process(), which clears
  1695. // the area or draws a horizon (see RENDERER.H) in the area.
  1696. // Then the renderer itself is called to draw in the window.
  1697. // Finally, postrender_process() is called to add overlays
  1698. // such as status or axis compass.  These routines are easily
  1699. // customized, and are in USCREEN.C:  Look at REFRESH.C to
  1700. // see the sequence of calls.  For stereoscopic rendering,
  1701. // the sequence is repeated twice.
  1702.  
  1703. // Routines in USERVID.C:
  1704.  
  1705. // These are the colors used to draw in the world.  For two-color
  1706. // horizons, sky_color and ground_color set the horizon: if the
  1707. // same. the whole window is cleared.  screen_clear_color is used
  1708. // if the screen must be completely blanked.  Highlight_color
  1709. // is used to outline selected objects.
  1710.  
  1711. extern WORD screen_clear_color;
  1712. extern WORD sky_color;
  1713. extern WORD ground_color;
  1714. extern WORD highlight_color;
  1715.  
  1716.    // call on initialization to set defaults for the colors
  1717.    // listed above. the video driver These vary depending on
  1718. void preset_default_colors();
  1719.  
  1720.    // This structure is actually part of the video driver.
  1721.    // It has information on the driver's screen size,
  1722.    // aspect ratio and number of colors.
  1723.  
  1724. extern struct Screeninfo *screeninfo;  // ptr to data in video driver
  1725.  
  1726. //struct Screeninfo {
  1727. //             WORD xmin;       // left edge of useable area
  1728. //         WORD ymin;     // top edge
  1729. //         WORD xmax;     // right edge
  1730. //         WORD ymax;     // bottom + 1
  1731. //         WORD xcent;    //
  1732. //         WORD ycent;    // where text boxes, menus should be centered
  1733. //         WORD colors;   // number of colors supported
  1734. //         WORD pages;    // number of video pages
  1735. //         WORD bw;       // monochrome only flag
  1736. //         SCALE aspect;  // vertical/horizonal pixel size * 65536
  1737. //         char id[80];   // driver title
  1738. //           };
  1739.  
  1740.  
  1741. /********************************************************/
  1742. /* USER ROUTINES CALLED BY THE RENDERING LIBRARY        */
  1743. /* KEEP THIS AS FAST AS POSSIBLE: SOME MAY BE           */
  1744. /* CALLED UP TO 1000 TIMES PER SCREEN!                  */
  1745. /********************************************************/
  1746.  
  1747. /* USER ROUTINE TO SETUP FOR POLY DRAWING - CALLED ONCE PER FRAME */
  1748. void user_setup_blitter();
  1749.  
  1750. /* USER ROUTINE TO RECOVER AFTER POLY DRAWING: ONCE PER FRAME */
  1751. void user_reset_blitter();
  1752.  
  1753. /* CALLED FROM RENDERER TO DRAW POLYS, LINES, POINTS */
  1754. /* <color> was created by colormap.c: modify it to   */
  1755. /* do your own special color modes/effects!          */
  1756. // supplied data: number of points, array of (x,y) screen coords (WORD),
  1757. // color value generated by COLORMAP.C function user_poly_color(),
  1758. // and the depth of the deepest point in polygon.
  1759.  
  1760. void user_render_poly(WORD number, WORD *pcoords, SURFACE color, COORD maxz);
  1761.  
  1762. // These routines draw items for the user interface.
  1763. // Colors are entries in the screen palette
  1764. // All are drawn to current video page
  1765.  
  1766.     /* Draws filled box for text and menus
  1767.     // color is entry in color palette
  1768. void user_box(WORD x1, WORD y1, WORD x2, WORD y2, WORD color);
  1769.  
  1770.     // draws a line on the screen (current page)
  1771. void user_draw_line(WORD x1, WORD y1, WORD x2, WORD y2, WORD color);
  1772.  
  1773.     // draws a box outline on the screen (current page)
  1774. void user_draw_box(WORD left, WORD top, WORD right, WORD bottom, WORD color);
  1775.  
  1776.     /* USER ROUTINES TO DRAW TEXT */
  1777.     // These will draw reversed text if the current page's
  1778.     // orientation requires it.
  1779. void user_text(WORD x, WORD y, WORD color, char *string);
  1780.  
  1781.     // draws text with a black shadow (color 0)
  1782. void shadowprint(WORD x,WORD y, WORD color, char *t);
  1783.  
  1784. /////////////////////////////////////////////////////////////////
  1785. /// USER VIDEO MODE SUPPORT ROUTINES:
  1786. ///
  1787. /// NEVER CHANGE MOST OF THESE UNLESS YOU NEED
  1788. /// MORE THAN THE VIDEO DRIVERS CAN DO
  1789.  
  1790.      /* enter and setup graphics screen */
  1791.      // required to initialize all screens for
  1792.      // multi-VGA driver
  1793. void enter_graphics(unsigned vdmode, int bw);
  1794.  
  1795.       /* exit and restore text screen */
  1796.       // must reset all screen for
  1797.       // multi-VGA driver
  1798. void exit_graphics();
  1799.  
  1800.      // clear full video page: rarely needed
  1801. void clear_display(WORD pge);
  1802.  
  1803.     // This is the "critical" function when your screen
  1804.     // has complex borders for the view window.  It is
  1805.     // called when the size of the window changes, or
  1806.     // there is a chance the the border has been munged.
  1807.     // It is also called on startup.
  1808.     // If you have no border, just clear all the video
  1809.     // pges.  If you have a border, redraw it on one
  1810.     // page and copy it to all other pages.
  1811. void reset_screens();
  1812.  
  1813.  
  1814. // IN <REFRESH.C>
  1815.  
  1816. void screen_refresh(CAMERA *c);
  1817.  
  1818. // This is the main screen-refresh routine.  It switches video pages,
  1819. // calls window clearing, rendering, and postrender overlay routines.
  1820. // It draws the current world with the given camera (which also specifies
  1821. // where on the screen it is to draw).  The proper stereo mode is set by:
  1822.  
  1823. extern WORD stereo_type;
  1824.  
  1825. #define MONOSCOPIC 0 /* stereo types */
  1826. #define SWITCHED   1
  1827. #define SPLITLR    3
  1828. #define SEPARATE   5
  1829.  
  1830. //These variables are updated by screen_refresh():
  1831.  
  1832.     // where to save the screen while using menus
  1833. extern WORD screen_save_video_page;
  1834. extern BOOL screen_has_been_saved;
  1835.  
  1836. extern WORD current_video_page;     // current video page
  1837. extern WORD current_orientation;    // flip flags of current page
  1838.  
  1839. // This routine is called by user interface routines to stop
  1840. // the flicker of SWITCHED stereo displays.
  1841.  
  1842. void stop_stereo();
  1843.  
  1844. // This routine can be called by user postrender() routines to
  1845. // draw an axis compass on the screen.  Use the VIEW passed to
  1846. // postrender()-- it contains window edges and the view matrix.
  1847.  
  1848.     // xc,yx : screen location of center
  1849.     // V : viewport structure
  1850.     // xcolor,ycolor,zcolor: color of axes
  1851.     // bcolor: "shadow" color
  1852. void coord_ref(WORD xc, WORD yc, WORD size, VIEW *v,
  1853.               WORD xcolor, WORD ycolor, WORD zcolor, WORD bcolor);
  1854.  
  1855.  
  1856. // Internally, screen_refresh uses this function from SCAMERA.C
  1857. // to get monoscopic, left, or right eye views from the
  1858. // camera to control rendering.  The renderer is set up by
  1859. // the routine to use the VIEW, and it is returned so it may be
  1860. // passed to user routines.
  1861.  
  1862.     // sets renderer to draw a view, mono or stereo view
  1863.     // also copies segment position
  1864. VIEW *select_camera_view(CAMERA *c, WORD which_eye);
  1865.  
  1866.  
  1867. // IN USCREEN.C
  1868.  
  1869. //////////////////////////////////////////
  1870. ///  THESE ROUTINES LET YOU CONTROL HOW THE
  1871. ///  SCREEN IS CLEARED AND WHAT IS DISPLAYED
  1872. ///  THE ARGUMENTS ARE:
  1873. ///  v : the view being draw.  left/right eye views are different
  1874. ///  vpage: the video page being drawn
  1875. ///  isfirst, islast:  1 if this is the first/last access to the
  1876. ///                    video page.  Useful for toggling screen
  1877. ///               clears etc. when several views are on the
  1878. ///               same page
  1879. ///  whicheye:  0 for left eye/mono, 1 for right eye view
  1880. ///
  1881.  
  1882.  
  1883. // found in <USCREEN.C>
  1884.  
  1885.     // This is called before drawing objects.  It should
  1886.     // at least clear the screen
  1887.  
  1888. void prerender_process(VIEW *v, WORD vpage, WORD isfirst, WORD whicheye);
  1889.  
  1890.     // This is called after drawing objects.  It can be used
  1891.     // to put up status, etc.
  1892.     // lots of if() stuff, but just because we're supporting
  1893.     // so many stereo types
  1894.  
  1895. void postrender_process(VIEW *v, WORD vpage, WORD islast, WORD whicheye);
  1896.  
  1897.  
  1898.  
  1899.  
  1900. /////////////////////////////////////////////////////
  1901. ////                                             ////
  1902. ////       USER NAVIGATION AND JOYSTICK             ////
  1903. ////                                             ////
  1904. /////////////////////////////////////////////////////
  1905.  
  1906. // The currently implemented navigation method in VR-386 uses
  1907. // a 2D device: a joystick.  Two buttons are used to map this
  1908. // 2D to full 6D motion.  Joystick "devices" include PC game
  1909. // port, mouse, key press, and key-down monitor.
  1910. //
  1911. // The joystick devices are read through the regular pointer
  1912. // interface, and are implemented in JOYPTRS.C.  Up to 9
  1913. // devices may by polled for motion (NAVJOY.C), with the sum
  1914. // of all device's effects used to move the user.
  1915. // All navigation devices (even key presses) are mapped
  1916. // through pointer devices.  Please look at JOYPTRS.C
  1917. // to see how easy and flexible this tecnique is.  The
  1918. // pointer devices need only return buttons and the
  1919. // relative (change) motion required.
  1920.  
  1921. // Joystick devices are added with:
  1922.  
  1923. BOOL add_joy_device(char *name);
  1924.  
  1925. // which loads and/or initializes the pointer driver for the
  1926. // joystick, then adds it to the list of drivers.  New drivers
  1927. // can be added or created by adding to the internal driver table
  1928. // in POINTER.C, and adding a new pointer driver and pconfig.
  1929.  
  1930. // The joysticks are processes to move a POSE structure to move
  1931. // the user's body or point of view.
  1932.  
  1933.     // <body_pose> is the POSE to move user with
  1934.     // <spinmode>: if true, maps all motion to rotation
  1935.     // <sstep>: scaling of position changes: 100 is usual
  1936.     // <astep>: scales turning: angle2float(20) is usual
  1937.     // <flymode>: makes all motions relative to the
  1938.     // view direction.  Otherwise, motion is relative
  1939.     // to the "ground" always.
  1940.     // RETURNS: TRUE if body has been moved by any device
  1941.  
  1942. BOOL do_joy_navigate(POSE * body_pose, BOOL spinmode,
  1943.              COORD sstep, ANGLE astep, BOOL flymode);
  1944.  
  1945. // The main loop of VR-386 is written to call joystick_process().
  1946. // This routine is found at the end of KEYBOARD.C, and can easily
  1947. // be modified to remove unwanted options.
  1948.  
  1949. extern void joystick_process();
  1950.  
  1951. // The usual POSE to set user position is *body_pose.  This
  1952. // is used by world and teleports as well.
  1953.  
  1954. extern POSE initial_body_pose;    // start position
  1955. extern POSE *body_pose;           // current "teleport" used
  1956.  
  1957. // See PCDEVICE.H for more information on the PC game port joystick device.
  1958.  
  1959.  
  1960. /////////////////////////////////////////////////////
  1961. ////                                             ////
  1962. ////       USER BODY AND TELEPORTS                  ////
  1963. ////                                             ////
  1964. /////////////////////////////////////////////////////
  1965.  
  1966. // To use head trackers and 3D manipulators such as the PowerGlove,
  1967. // a set of invisible connected objects is used to build the user
  1968. // a body.  The body_seg is the root of the body, which is moved
  1969. // through the world by the navigation "joystick" devices.  The body can
  1970. // also be attached to other objects, thus letting the user "ride"
  1971. // the object as it moves.  Joystick motion is then relative to
  1972. // the object instead of the world.
  1973. //
  1974. // The head tracker moves the head_seg relative to the body,
  1975. // and the default_camera (user's viewpoint) is attached to
  1976. // the head_seg.  This is an elegant implementation of head
  1977. // tracking.
  1978. // There is also a wrist_seg attached to the body.  It is used with
  1979. // the PowerGlove or 3d/6d pointer devices, and used to "hold" the
  1980. // glove or pointer 3D cursor.  It is also used to manipulate objects.
  1981. //
  1982. // These link objects are created during initialization by a call to
  1983.  
  1984. void init_body_links();
  1985.  
  1986. extern OBJECT *body_seg, *wrist_seg, *head_seg;
  1987.  
  1988. // which creates these links, and attaches the camera to the head.
  1989. // You can easily eliminate the body code in BODY.C if you wish to have a
  1990. // simpler viewpoint metaphor.  But you will also have to eliminate
  1991. // all head tracker, PowerGlove, and 3D pointer support device.
  1992.  
  1993. // If the body has been moved for any reason, you must update the
  1994. // body links so the manipulation and camera positions will be
  1995. // current.  Do this by a call to
  1996.  
  1997. void update_body_links();
  1998.  
  1999. // This will already have been done if the body is attached to an
  2000. // object that was moved then updated.
  2001.  
  2002. // To attach the body to objects, it is recommended that you use
  2003. // these functions from BODY.C:
  2004.  
  2005.     // disconnects body from any object currently attached to
  2006. void disconnect_body();
  2007.  
  2008.     // connects body to new ovject (disconnects old object if any)
  2009. void connect_body(OBJECT *s);
  2010.  
  2011.     // This variable records curent object: NULL if none
  2012. extern OBJECT *body_vehicle_object;
  2013.  
  2014.  
  2015. // TELEPORTs are records of user positions and status.
  2016. // They record the world, pose (as seen in *body_pose),
  2017. // and the object the user is connected to (for moving).
  2018. // They are used to implement the HOME key, as well as
  2019. // the F1..F10 "cameras" (which aren't cameras, but were
  2020. // called that in the REND386 .WLD files!).
  2021.  
  2022. // The basic TELEPORT operations are create, delete,
  2023. // record pose and "vehicle" object, and execute.  At
  2024. // present. between-world teleports are not implemented,
  2025. // until WORLD support for this is implemented.
  2026.  
  2027.     // create. record present pose, world, vehicle
  2028. TELEPORT *create_teleport();
  2029.  
  2030.     // release memory of TELEPORT
  2031. void delete_teleport(TELEPORT *t);
  2032.  
  2033.     // record where to teleport to
  2034. void teleport_set_here(TELEPORT *t, POSE *p);
  2035.  
  2036.     // what we're attached to at teleport entry
  2037. void teleport_set_vehicle(TELEPORT *t, OBJECT *vehicle, char *vname);
  2038.  
  2039.     // go to the teleport position/world
  2040.     // updates *body_pose and reconnects body
  2041. void teleport_to(TELEPORT *t);
  2042.  
  2043.  
  2044. /////////////////////////////////////////////////////
  2045. ////                                             ////
  2046. //// POWERGLOVE, MANIPULATION AND DEVICE SUPPORT ////
  2047. ////                                             ////
  2048. /////////////////////////////////////////////////////
  2049.  
  2050. // Other than the mouse manipulation routines in KEYBOARD.C,
  2051. // objects may be manipulated with a 3D or 6D pointer device,
  2052. // or with the PowerGlove.  These routines are well encapsulated
  2053. // so little effort is needed to support them: just initialize
  2054. // and call them in the main loop.
  2055.  
  2056. // These routines should be given a driver file or internal
  2057. // driver name, the name of a .PLG file for the 3D pointer,
  2058. // and the name of a .FIG file for the glove's hand object.
  2059. // The POSE is for scaling: it should contain a SCALE value
  2060. // for all parameters. (i.e use float2scale() )
  2061. // These are already done based on the .CFG file in INIT.C
  2062.  
  2063.     // initialize a 3D/6D pointer device
  2064. PDRIVER *pointer_initialize(char *ptrdrv, char *ptrobj, POSE *scale);
  2065.  
  2066.     // initialize the PowerGlove
  2067. PDRIVER *glove_initialize(char *glvdev, char *glvobj, POSE *scale);
  2068.  
  2069. // To use the devices, simply call one of these in the main loop.
  2070. // It reads the device, moves the image of the device, and looks
  2071. // for button or gesture to control manipulation.
  2072.  
  2073.     // read, handle 3D/6D pointer commands
  2074. void pointer_process();
  2075.  
  2076.     // read, handle glove gestures
  2077. void glove_process();
  2078.  
  2079. // Internally, the processing routines call this routine to
  2080. // actually grasp, release, and rotate objects.  The commands
  2081. // passed depend on the current gesture or button state:
  2082.  
  2083.     // 3D/6D select/move/rotate
  2084. void do_3D_manip(WORD command);
  2085.  
  2086.     // commands to do_3D_manip
  2087. #define FREE_DO   0        // released
  2088. #define GRASP_DO  1        // holding
  2089. #define ROTATE_DO 2        // "pinch" rotation emulation for 3D dev.
  2090. #define SELECT_DO 3        // looking for an object to grasp...
  2091.  
  2092. // Because a pointer device works in real-world coords, with
  2093. // Z going into screen, the pointer must be mapped to and from
  2094. // the internal world coord system, by these functions (POINTER.C)
  2095.  
  2096. void pointer_to_world(POINTER *p, CAMERA *c, long *x, long *y, long *z);
  2097. void rotate_to_view( CAMERA *c, long *x, long *y, long *z);
  2098.  
  2099.  
  2100.  
  2101. // For reportingthe current glove gesture, this function is useful:
  2102.  
  2103.     // returns text string with gesture,
  2104.     // or NULL if no glove
  2105. char *get_glove_gesture_name();
  2106.  
  2107. // Finally, we need a way to initialize the head tracker device.
  2108. // This function does that, given a driver file or device name.
  2109. // The POSE is the head tracker "offset": a matrix used to
  2110. // compensate for tilt and offset of tracker with respect
  2111. // to the user's head.
  2112.  
  2113. PDRIVER *init_head_device(char *dfname, POSE *hdo);
  2114.  
  2115. // and to process the tracker data :
  2116.  
  2117. void head_tracker_process();
  2118.  
  2119. // the PDRIVER arguments may be ignored as the driver address
  2120. // is kept internally by the support modules.  However, if NULL
  2121. // is returned by the initiializing functions, the driver could not
  2122. // be initialized.
  2123.  
  2124.  
  2125. /////////////////////////////////////////////////////
  2126. ////                                             ////
  2127. ////           INITIALIZATION AND PROGRAMS       ////
  2128. ////                                             ////
  2129. /////////////////////////////////////////////////////
  2130.  
  2131. // FOR OTHER INITIALIZATIONS, LOOK AT INIT.C, PCDEVICE.H ETC.
  2132. // SEE ALSO EXAMPLES IN MAIN.C
  2133.  
  2134.             // alternate-frame stero driver start
  2135.             // may take over timer
  2136. void init_switch_driver(char * swdname);
  2137.  
  2138. //////// FROM INIT.C
  2139.  
  2140.     // sets up renderer, memory, load video driver
  2141.     // Also reads config file, loads video driver
  2142. void preload_initialize(int argc, char *argv[]);
  2143.  
  2144.     // read configuration. mark loadable file args
  2145.     // loads .CFG flie, calls EMM init if used
  2146. void read_configuration(int argc, char *argv[]);
  2147.  
  2148. // This calls:
  2149. void read_config_file(FILE *in);
  2150.  
  2151.     // read input files from cmd line
  2152.     // loads .PLG, .WLD, and .FIG
  2153. void read_input_files(int argc, char *argv[]);
  2154.  
  2155.  
  2156.   // (WPARSE.C) This can load REND386 v5 .WLD files via a call to:
  2157. void read_world(FILE *in);
  2158.   // and retrieves name list memory later with a call to
  2159. void dump_lists();
  2160.  
  2161.   // If you want to use the standard lights, use this code from WPARSE.C
  2162.   // It creates the standard lights: one ambient, two point sources.
  2163. void create_default_lights();
  2164.  
  2165. extern LIGHT *std_lights[3];
  2166. extern LIGHT *amb_light;
  2167. extern LIGHT *light1;
  2168. extern LIGHT *light2;
  2169.  
  2170.     // report on memory use after loading
  2171.     // reports EMM use as well
  2172. void load_memory_report();
  2173.  
  2174.     // initialize video system, enter graphics mode
  2175. void video_initialize();
  2176.  
  2177.     // initialize all hardware devices and pointers
  2178. void device_initialize();
  2179.  
  2180.     // call at exit to reset all to DOS mode
  2181. void exit_handler(void);             /* end program */
  2182.  
  2183.  
  2184. /// MAIN PROGRAM: SHOULD:
  2185.  
  2186. // - call above initialization routines
  2187. // - set up any devices or items not set up by above.
  2188. // - start main loop, until running==FALSE:
  2189.  
  2190. extern BOOL running;
  2191. extern BOOL in_graphics;
  2192.  
  2193. // Main loop should do (in this order)
  2194.  
  2195.     // key scan, process keys for key joystick etc
  2196. extern void key_process();
  2197.  
  2198.     // read and proccess joystick navigation devices to move user
  2199. extern void joystick_process();
  2200.  
  2201.     // move cursor, select objects or menu commands
  2202. extern void mouse_process();
  2203.  
  2204.     // CALL ONLY IF THESE DEVICES ARE ACTIVE
  2205. extern void head_tracker_process(BOOL recenter);
  2206. extern void glove_process();
  2207. extern void pointer_process();
  2208.  
  2209.     // run any tasks, animations, etc.
  2210.     // also, update any objects changed by animation
  2211.  
  2212. // Now, refresh display if required.
  2213. // There are several flags which should be set
  2214. // if anything changes, and cleared when the
  2215. // screen is redrawn:
  2216.  
  2217. extern WORD world_changed, display_changed, position_changed;
  2218.  
  2219. // Suggested refresh:
  2220. //
  2221. //  update_body_links();
  2222. //  screen_refresh(current_camera);
  2223. //  position_changed = 0;
  2224. //  world_changed = 0;
  2225. //  display_changed = 0;
  2226.  
  2227. // SEE MAIN.C FOR EXAMPLE.
  2228.  
  2229.  
  2230. /////////////////////////////////////////////////////
  2231. ////                                             ////
  2232. ////        OTHER FUNCTIONS                      ////
  2233. ////                                             ////
  2234. /////////////////////////////////////////////////////
  2235.  
  2236. // ERROR REPORTING
  2237.  
  2238. extern FILE *log_file;    // error log file, opened in read_cfg
  2239.  
  2240.     // print error message in appropriate way(s)
  2241. WORD errprintf(char *fmt, ...);
  2242.  
  2243. // FILE NAME SUUPPORT
  2244.  
  2245.     // add extension to filename
  2246. void add_ext(char *name, char *ext);
  2247.  
  2248. extern char loadpath[100];    // default load path
  2249.  
  2250.     // adds default load path to filename
  2251. char *fix_fname(char *name);
  2252.  
  2253. ////////// PCXMODEY.C
  2254.  
  2255.     // load, save full-screen PCX file
  2256. load_pcx(FILE *in, int page);
  2257.  
  2258. save_pcx(FILE *out, int page);
  2259.  
  2260.  
  2261. //////////// DRVLOAD.C
  2262.  
  2263.     // load a video or pointer driver
  2264. void *load_driver(char *dfile);
  2265.  
  2266.  
  2267. ////// THESE ARE ALSO IN PCDEVICE.H
  2268.  
  2269. extern void tdelay(long msec);     /* replaces borland delay() */
  2270. extern long current_time(void);    /* returns time in msec */
  2271.     // returns count per int, speed is a hint (0 for default)
  2272. extern int init_timer(unsigned speed, void (*timer_hook)());
  2273. extern int init_frame_lock(unsigned speed, void (*frame_hook)());
  2274.  
  2275. extern int get_ticks_per_second(void); // always returns 1000
  2276.  
  2277.  
  2278.