home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / v / vrmlviewer / Docs / GeminiSpec next >
Encoding:
Text File  |  1997-02-08  |  43.7 KB  |  852 lines

  1. Gemini
  2. ======
  3. version     : 1.05
  4. questions to: Giancarlo Castagno (s64922@galileo.polito.it)
  5. disabled    : some lens-flares effects and some camera parameters.
  6.  
  7. © 1996 Sincronia Soluzioni Multimediali, Italy
  8.   It cannot be used without the written permission of Sincronia
  9.  
  10. Here follows a description of Gemini, the new TopModel's graphic engine.
  11. It is a relocatable module available also to third parties, as it can be shared
  12. across all the applications that need 3D visualisation. It lets users to
  13. display a 3D scene and navigate into it.
  14. Gemini can be run also on older machines (pre RiscPC, without dynamic areas).
  15. Applications that use it will work happily with all its the future versions as well.
  16. Module upgrades will offer automatic file loading and a common wimp
  17. interface (like the Acorn !ColourPicker one).
  18.  
  19. Gemini main features:
  20. =====================
  21. - Works on any Acorn processor, from ARM2 to StrongArm.
  22. - Phong illumination model and support for Cook&Torrance's one.
  23. - Wireframe, flat shading, gouraud shading and phong shading view modes.
  24. - Up to 1024 light sources per scene, of any type (sun, point, spot) and colour, all recalculated real-time.
  25. - Shaded wireframe, for high-speed illuminated rendering; this display style was originally
  26.   created by Sincronia and introduced in TopModel from its very first versions.
  27. - Phisical-based material models (ambient, diffusion, reflection RGB, transparency RGB
  28.   and refractive index).
  29. - Full Z-buffer (in any view mode), with a T-Buffer for a correct rendering of transparencies.
  30. - Real-time parametrized fog and haze.
  31. - Texture, chrome and bump mapping. Gemini supports also several techniques superposed.
  32. - Lens-flares effects.
  33. - Several camera models.
  34. - Normal and VR navigation modes.
  35. - Scene is always calculated at 96bits per pixel and then reduced using a real-time Floyd/Steinberg
  36.   error diffusion algorithm.
  37. - New enhanced radiosity view mode that deals with real-time soft shadows and light diffusion.
  38. - Possibility to place an image (in any format) in the background; it can follow the rotation
  39.   of the view (like a VRQuickTime).
  40. - Direct import of VRML files (up to 40 nested Separator nodes, support for recursive nested
  41.   DEF-USE nodes, gestion of lights and navigation nodes).
  42. - Support for animation: hierarchic objects management and a "Gemini_Transform" call to
  43.   move/scale/rotate them.
  44.  
  45. Gemini environment:
  46. ===================
  47.  
  48. Gemini is basically a collection of routines to manage a 3D database and render
  49. it both on the screen or to a memory area (to create a sprite); the code contains
  50. tables of precalculated datas (1/x, sin(x), 1/SQR(x) and so on). If you need to
  51. know how to use them not to duplicate informations (i.e. if you need to use
  52. them too), ask us for the full specs...
  53. All the relevant informations on how to render the files are stored within the
  54. application using it. That's why it can be shared istantly beetween applications.
  55. Gemini is simple to use, as it only has three main calls: one for initialise itself,
  56. one to set the workarea and one to draw the whole scene. The tricky part of the
  57. system are the memory areas used to make it work. You can simply set them big enough
  58. (go on reading this file), without bother why they are needed. Anyway better if you
  59. understand fully how the whole system works and what are the main memory areas used...
  60.  
  61. A 3D scene is made of 2 separated database, for speed & memory needs: a points
  62. database, which contains all the points used by the model (X,Y,Z of the point
  63. plus some infos) and a primitives database, that contains the description of
  64. each primitive (polygon, sphere or Bezier line/surface) used. For example, this
  65. is a reduced GEO file which describes a cube that can be used to provide a good
  66. example of how the data bases work:
  67.  
  68. 8                    | total number of points
  69. 0 0 0                | points 0: X Y Z
  70. 1 0 0                | points 1: X Y Z
  71. 1 1 0                | ...
  72. 0 1 0                | ...
  73. 0 0 1                |
  74. 1 0 1                |
  75. 1 1 1                |
  76. 0 1 1                |
  77.                      |
  78. 4 0 1 2 3            | polygon of 4 sides, connecting points 0,1,2,3
  79. 4 7 6 5 4            | polygon of 4 sides, connecting points 7,6,5,4
  80. 4 0 4 5 1            | ...
  81. ...                  | ...
  82.  
  83. Obviousely TopModel files use the memory location of a point (from now on LDM)
  84. instead of its number for speed needs, but basically this is the structure.
  85. It allows to share points between polygons (a cube uses 8 points and 6 polygons,
  86. instead of 24 points (4 for each poly) and 6 polygons).
  87. A TopModel file is basically a memory dump of these two TopModel work areas,
  88. plus some other informations (for example the minimum size of each area).
  89. So, before loading a file you have to reserve enough workspace for it. If you
  90. want to speed up things, you can simply reserve a memory area as big as the 3Dfile
  91. size, (plus 2/3 Kbytes for security... ;-). The areas can be stored within your
  92. application workspace or in a dynamic area, and can be two different areas or
  93. just one splitted. Gemini needs only to know where Points and Primitives areas
  94. start in memory.
  95.  
  96. Please note: Gemini (and TopModel) uses the first 58 points for internal use (axis
  97. and so on); thus you must reserve them (32 bytes each, so 58*32 bytes) at the
  98. start of the Points area. So, once you have dimensioned enough workspace for points,
  99. starting from an ldm stored in the variable PointsLDM, you should load the Points
  100. informations of the file at PointsLDM+58*32.
  101.  
  102. There is another memory area to store the main resources: a table of presetted
  103. (plus user defined) colours and materials definition plus a table for textures
  104. and groups setup.
  105.  
  106.   TopModel (and Gemini) manages 512 colours, (up to 200 presetted and up to 311
  107.   user defined). Each colour uses 16 bytes (0-11 for the name and 12-15 for the
  108.   &BBGGRR00 of the colour palette). So you have to reserve a 512*16 bytes for
  109.   the colour table. In the same way TopModel stores also the 256 materials
  110.   (up to 100 predefined and up to 155 user defined). Each material uses 32 bytes
  111.   (0-11 for the name 12-31 for material definition). Thus you have to reserve
  112.   256*32 bytes for the material table. In this area you should also store the
  113.   texture information table. Gemini manages up to 512 textures and each entry in
  114.   table is 16 bytes long, so you have to reserve another 512*16 bytes.
  115.   Texture 0 is reserved to say "No texture", so its values in the table should
  116.   always remains 0; the first valid texture entry is n^1 (at the offset +16). The
  117.   entry for each texture are:
  118.     +0 =ldm of the sprite;
  119.     +4 =X dimension of the sprite (pixel);
  120.     +8 =Y dimension of the sprite (pixel);
  121.     +12=2^29 (or colour (at 16bpp) to be made transparent).
  122.   Finally this buffer holds also group datas. Gemini allows up to 2048 groups to
  123.   be defined, and each of them uses 8 bytes. Thus this area needs 2048*8 bytes.
  124.   When you call "Gemini_Initialise" for the first time, it fills this buffer
  125.   with the predefined materials and colours and zeroes the textures and groups tables.
  126.   To do this, set the bit 1 int the flag word (R4).
  127.   Every TopModel file (&B5C) may contain some colours or materials created by user.
  128.   These should be loaded from the 200th colour (offset +200*16) and from the 100th
  129.   material (offset +100*32). Look at the loading procedure (see later) to see how
  130.   they are loaded. The total size of the area is 40960 bytes (512*16+256*32+512*16+2048*8).
  131.  
  132. After that you should create a normal sprite area defined in RiscOS, in which
  133. you have to load the textures used, taking them from inside the Resources
  134. folder. In the file you find the path of each texture used inside the
  135. "!TopRes.texture" directory (the system variable <TopModel$Textures> holds the full path.
  136. You may need to use !ChangeFSI if the textures aren't 16bpp RiscOS Sprites, as Gemini
  137. can manage only them; once loaded you should set the corrispondent table entry
  138. with the texture ldm and dimensions. If you want to discard textures, simply don't
  139. load them, leaving the texture table filled with 0s.
  140.  
  141. Then you have to reserve some memory for the Z buffer. The exact amount
  142. depends upon the size of the image to be created. Gemini uses 4 bytes for each pixel
  143. of the image. Last but not least there is the image buffer. You can plot directly
  144. on the screen, and in this case you don't have to dimension nothing, or you may
  145. want to plot to sprite. In this case you need as much memory as the one required
  146. to store a normal RiscOS sprite in the resolution and number of colours you need.
  147.  
  148. To sum up: you have to set 5or6 work areas:
  149.   1) Points     workarea (the file contains the minimum size)
  150.   2) Primitives workarea (the file contains the minimum size)
  151.   3) Colours+Material+Textures+Groups table (40960 bytes (512*16+256*32+512*16+16384))
  152.   4) Texture sprite area (big enough to load all the 16bpp sprites)
  153.   5) Z buffer (4 bytes for each pixel of the image to be created)
  154.   6) image buffer (if you aren't plotting to the screen): the same size of a RiscOS sprite.
  155.  
  156. Obviously you can store all of them in a single area or split them on several
  157. segments. Note: ALL THEM MUST BE WORD ALIGNED!
  158.  
  159. Now Gemini is ready to work happily within your application.
  160. There are three main blocks of informations to drive Gemini engine.
  161. I call them TMmemoryblock, TMviewblock, TMcolourblock.
  162.  
  163.   TMmemoryblock (256 bytes)
  164.   -------------------------
  165.     it contains the relevant memory information for Gemini. Some of the
  166.     locations are updated, some other are filled with ldm of tables of
  167.     precalculated datas. These must be filled:
  168.  
  169.     +0  ldm start of Points workspace
  170.     +8  dimension of Points workarea in bytes
  171.     +12 ldm start of Primitives workspace
  172.     +20 dimension of Primitives workarea in bytes
  173.     +40 ldm start of Z buffer
  174.     +44 ldm colours+materials+textures+groups table
  175.  
  176.  
  177.     Other relevan values, set by "Gemini_Initialise", when you call it with
  178.     bit 0 (in the flag word) set, are:
  179.  
  180.     +4  first free location in Points workspace (where to load Points from
  181.         file). Updated when loading the file (or editing it).
  182.     +16 first free location in Primitives workspace (where to load Points
  183.         from file). Updated when loading the file (or editing it).
  184.     When no object is loaded, the default values are:
  185.                             TMmemoryblock!4 =TMmemoryblock!0 +58*32
  186.                             TMmemoryblock!16=TMmemoryblock!12
  187.     +52 ldm of texture table
  188.     +64 ldm of materials table
  189.     +68 ldm of groups table
  190.     These three are used by Gemini to speed up things. Instead of recalculating each time
  191.     the ldm of the start of each area, Gemini simply calculates them once when a
  192.     "Gemini_Initialise" is called, storing the start ldm of textures, materials and groups
  193.     tables out of the address you pass in TMMemoryblock!44.
  194.     Simply: +44 colours+materials+textures+groups table; this is also the ldm of
  195.                                             the start of colour area:  512*16 bytes
  196.             +52 texture table:       (previous ldm + 512*16); it uses  256*32 bytes
  197.             +64 materials table:     (previous ldm + 256*32); it uses  512*16 bytes
  198.             +68 groups table:        (previous ldm + 512*16); it uses 2048*8  bytes
  199.  
  200.   TMviewblock (256 bytes)
  201.   -----------------------
  202.     it contains all the relevant parameters to drive the shading process. Some
  203.     locations are updated and some others are filled with some infos about the
  204.     current screen modes and so on. For a full list, ask me. The values
  205.     inside [] are the default values set when you call "Gemini_Initialise". All
  206.     the values must be integers, so to keep some precision, your numbers are
  207.     multiplied by some factor. To obtain their original value, just take the value
  208.     stored inside the corresponding location and divide it by the multiplier
  209.     factor (eg. if you have 0.5 and a multiplier factor of 2^16, you should
  210.     store the number 2^16*0.5=2^15=32768. When you need to know its value,
  211.     read it and divide it by 2^16, so 2^15/2^16=0.5). You have to alter only the
  212.     values you are interested in.
  213.  
  214.     +0   Z angle of view *16 (so 0 <= Zangle <= 360*16).To rotate around Z [ 0*16]
  215.     +4   Y angle of view *16 (so 0 <= Yangle <= 360*16).To rotate around Y [90*16]
  216.     +8   0 (for the X angle, but currently unused)                         [ 0*16]
  217.     +12  X position of the observer (*2^17) To pan around                  [ 0*2^17]
  218.     +16  Y position of the observer (*2^17)                                [ 0*2^17]
  219.     +20  Z position of the observer (*2^17)                                [ 0*2^17]
  220.     +24  current OS version (currently unused)
  221.     +28  zoom factor *2^10 ( 1*2^10 =100%)   Note: (0 <= zoom <= 64*2^10)  [ 5*2^10]
  222.     +44  distance observer-plane of projection (*2^17). Used to alter the
  223.          perspective deformation (works just in perspective...)            [10*2^17]
  224.     +100 Linear FOG intensity *2^14 (0 <= intensity <= 4*2^14)             [ 1*2^14]
  225.     +104 Z coordinates at which the fog starts (*2^17).                    [ 0*2^17]
  226.     +108 Z intensity of the fog *2^14  (0 <= height <= 4*2^14)             [ 1*2^14]
  227.     +112 Sun light X direction (the X component of the normal)             [ 0*2^15]
  228.     +116 Sun light Y direction                                             [ 0*2^15]
  229.     +120 Sun light Z direction                                             [ 1*2^15]
  230.     +124 Sun light intensity       (0..1 *2^16)                            [ 1*2^16]
  231.     +128 Sun light colour          (&BBGGRR00)                             [&FFFFFF00]
  232.     +132 Ambiental light intensity (0..1 *2^16)                            [ 0*2^16]
  233.     +136 Ambiental light colour    (&BBGGRR00)                             [&FFFFFF00]
  234.     +140 "Illumination has changed" flag                                   [255    ]
  235.     +144 Gemini_version set in Gemini_Initialise                           [104    ]
  236.     +156 "Colours have changed" flag                                       [255    ]
  237.     +172 precision in drawing a bezier curve        (1=high...6=low)       [3      ]
  238.     +176 precision in drawing a bezier surface      (1=high...6=low)       [5      ]
  239.     +192 "Geometry has changed" flag                                       [0      ]
  240.     +200 bits 0 -8 : texture used for picture in background (0=none)       [0      ]
  241.          bit  9    : set to 1 if texture must rotate with the view         [0      ]
  242.          bits 10-20: X offset on screen                                    [0      ]
  243.          bits 21-31: Y offset on screen                                    [0      ]
  244.     +204 Parametric grid: step X (*2^17)                                   [ 4*2^17]
  245.     +208 Parametric grid: step Y (*2^17)                                   [ 4*2^17]
  246.     +212 Parametric grid: step Z (*2^17)                                   [ 4*2^17]
  247.     +216 Parametric grid: number of points for each side                   [50     ]
  248.     +220 Parametric grid: centre X (*2^17)                                 [ 0*2^17]
  249.     +224 Parametric grid: centre Y (*2^17)                                 [ 0*2^17]
  250.     +228 Parametric grid: centre Z (*2^17)                                 [ 0*2^17]
  251.  
  252.   Note: set the three flags (+140,+156,+192) to tell Gemini to recalculate the
  253.         correspondent value: +140 (illumination) if you have changed front light
  254.         or you have moved the lights in the scene; +156 (colours) if you have
  255.         changed some values in TMcolour block; +192 (geometry) if you want to
  256.         recalculate all the normals of points and primitives in the scene
  257.         (for example if you have deformed some objects or you simply want to
  258.         calculate normals of objects you have created yourself). Gemini will
  259.         recalculate the correspondent values next time you issue a "Gemini_Render"
  260.         call, then it will reset them to 0 (you need to calculate those things
  261.         just once).
  262.  
  263.   TMcolourblock (256+1024*4 bytes)
  264.     it contains all the colours used in the Gemini environment. They are stored
  265.     separately, because Gemini recalculates them each time a user change
  266.     graphic mode. The 1024*4 additional bytes are used to store a table of user
  267.     defined lights. See later. Each colour entry uses 8 bytes; 4 for &BBGGRR00
  268.     of the colour and the second 4bytes to store the translated colour for the
  269.     current graphic mode. The values inside [] are the default values set when
  270.     you call "Gemini_Initialise".
  271.     Once Gemini is running, if you want to change a colour (say the fog colour)
  272.     just alter the corrispondent location with the new palette entry and then
  273.     inform Gemini that you have changed colour setting TMviewblock!156 to a
  274.     value different from 0. Gemini will recalculate the new colour table next
  275.     time a "Gemini_Render" call is issued and zeroes this location (+156) on exit.
  276.  
  277.     +0   Background colour (or sky start,for shaded background)    [&AA999900]
  278.     +8   Active plane colour                                       [&00FFFF00]
  279.     +16  Active axis colour                                        [&0000FF00]
  280.     +24  Fog colour                                                [&AA999900]
  281.     +32  Sky end colour      (shaded background - disabled)        [&FF000000]
  282.     +40  Ground start colour (shaded background - disabled)        [&BF444400]
  283.     +48  Ground end colour   (shaded background - disabled)        [&00FF2200]
  284.     +56  Bezier visual-hull lines colour                           [&FFD53B00]
  285.     +64  Polygons' vertices colour                                 [&00FFA000]
  286.     +72  Bezier control-points colour                              [&FF000000]
  287.     +80  Selected points colour                                    [&0000FF00]
  288.     +88  Lattice deformation   (used in TopModel editor)           [&00FFFF00]
  289.     +96  Colour of active path (used in TopModel editor)           [&00FFA000]
  290.     +104 Colour of grid        (mainly used in TopModel editor)    [&FFFFFF00]
  291.  
  292.  
  293. Please note: Gemini, apart from the lights stored within a TopModel file, works
  294.  with two ever present lights: a general sun light and an ambiental one (as you
  295.  see from the structure of TMviewblock). To disable them just set their
  296.  intensity to 0. If you want to light the scene frontally, you should set the
  297.  sun beam direction (TMviewblock!112,116,120) to the values contained in
  298.  TMviewblock!48,52,56 respectively, which hold the current view vector. After
  299.  this you should inform Gemini that illumination has changed, setting
  300.  TMviewblock!140 to a value different from 0. In this way, next time you issue
  301.  a Gemini_Render call, Gemini will recalculate illumination before drawing the
  302.  scene. Gemini will automatically reset this location to 0 on exit.
  303.  
  304.  
  305. Now let's come to the Gemini calls.
  306. First of all you must initialise your workareas (TMmemory and view blocks):
  307.  
  308. SYS"Gemini_Initialise"
  309. ----------------------
  310. R0 = TMmemoryblock
  311. R1 = TMviewblock
  312. R2 = TMcolourblock
  313. R4 = flags:  Bit   Meaning if set
  314.             ---------------------------------------------------------------------------
  315.               0  | Initialise Points&Primitives workarea and zeroes textures and groups
  316.               1  | Reset colour&material table loading the default colours and materials
  317.               2  | Reset TMviewblock & TMcolourblock entries to their defaul values
  318.             3-31 | reserved - must be 0
  319.  
  320. On exit, this call also returns the Gemini version number*100, in TMviewblock!144
  321.  
  322. The first time you call "Gemini_Initialise" you should set R4 to 7 (set bits 0-2)
  323. This loads the colour and material default definitions and clear the scene, filling
  324. with 0s the texture table and setting the right values in the first 58 points.
  325. It also updates the Point's and Primitive's first free ldm (TMmemory+4 and +16).
  326. In this way, when you issue a Gemini_Render call, after this, Gemini will display
  327. just the axis in the centre of the workarea.
  328. Then you can call "Gemini_Initialise" each time you need to reset your scene (delete
  329. the objects inside) setting R4 to 1.
  330.  
  331.  
  332.  
  333.  
  334. SYS"Gemini_InitScene"
  335. ---------------------
  336. When you have loaded a file you have to adjust all its internal links (i.e. the
  337. ldm of the points used by the polygons); you should call this from inside the loader
  338. code (see later).
  339.  
  340. R1 = offset to add to the points
  341.        [(current location at which points are loaded in memory)-(the old location
  342.          from where they were saved, stored in the file)]
  343. R2 = offset to add to the primitives
  344.        [idem]
  345. R3 = location at which points     are loaded (TMmemoryblock!4 , mostly)
  346. R4 = location at which primitives are loaded (TMmemoryblock!16, mostly)
  347.  
  348.  
  349.  
  350.  
  351. SYS"Gemini_SetUpLights"
  352. -----------------------
  353. After loading a file, you should compile a light table, to access quickly to
  354. the light informations. The lights (up to 1024 per scene) are memorized in a
  355. table (of 1024*4 bytes) within the TMcolour block. You only have to dimension
  356. correctly the TMcolourblock and call this routine, which scans the Point database
  357. (in which lights are stored) and compile a table of ldm of the lights in memory.
  358. Then recalculates also the illumination of Points and primitives...
  359.  
  360. entry:
  361. R0 = TMmemoryblock
  362. R1 = TMviewblock
  363. R2 = TMcolourblock
  364. exit:
  365. R4 = n^ of lights found
  366.  
  367. ||| If you want to move your scene in memory, once you have loaded and used it,
  368. ||| just move phisically the memory, update the links within TMmemoryblock
  369. ||| (+0 to +20), call "Gemini_InitScene" with the new parameters; then
  370. ||| call "Gemini_SetUpLights".
  371.  
  372.  
  373.  
  374.  
  375. Then you must specify the dimension of the work area. You must call these
  376. routine every time (1) you want to change the image size or
  377.                    (2) a change of the desktop palette or of the graphic mode
  378.                        has occurred.
  379. There are two routines, which let you specify if you want to work on the screen
  380. or in a memory buffer (you have to call only one of these):
  381.  
  382. (a) SYS"Gemini_SetUpScreen"
  383.     -----------------------
  384.     This allows you to output the scene on the screen. You have to set:
  385.     R0 = TMmemoryblock
  386.     R1 = TMviewblock
  387.     R2 = TMcolourblock
  388.     R3 = X min workarea (OS units, inclusive)
  389.     R4 = Y min workarea (OS units, inclusive)
  390.     R5 = X max workarea (OS units, inclusive)
  391.     R6 = Y max workarea (OS units, inclusive)
  392.     R7 =   0 (for a complete setup, which recalculates also the colour tables for the current palette)
  393.          <>0 (window/workarea resize only, much faster)
  394.  
  395. (b) SYS"Gemini_SetUpSprite"
  396.     -----------------------
  397.     This allows you to output the scene on a sprite. You must set:
  398.     R0 = TMmemoryblock
  399.     R1 = TMviewblock
  400.     R2 = TMcolourblock
  401.     R3 = sprite width  (in pixels)  Please note that the sprite width will be "corrected":
  402.                                      16 colours mode: rounded to a multiple of 8 pixels
  403.                                     256 colours mode: rounded to a multiple of 4 pixels
  404.                                     32K colours mode: rounded to a multiple of 2 pixels
  405.                                     16M colours mode: all values are accepted
  406.     R4 = sprite height (in pixels)
  407.     R5 = log2 bit/pixel (2=16colours  3=256colours  4=32Kcolours  5=16Mcolours)
  408.     R6 = pointer to control block of sprite area (it is reinitialized and must contain
  409.          (R3 * R4 * 2^R5 / 8 + 128)  bytes at least)
  410.  
  411.  
  412. On exit, both these calls fill in the TMviewblock with some informations. In
  413. particular (in TMviewblock):
  414.   +72 X min workarea (OS units)
  415.   +76 Y min workarea (OS units)
  416.   +80 X max workarea (OS units)
  417.   +84 Y max workarea (OS units)
  418. these may or may not be equal to those you pass as input. Coordinates are
  419. translated into memory addresses for plotting purposes, which MUST be byte
  420. aligned. In practice, only the X coordinates may be affected from this
  421. readjustament phase. In particular, when in a 4bpp mode, X workarea coordinates
  422. must be multiple of 2 pixels. From 8bpp modes upwards (and so also 16bpp and 32bpp)
  423. there aren't restrictions.
  424.  
  425. So: call Gemini_SetUpScreen (or _SetUpSprite) specifing your workarea, then
  426.     check which are the settings Gemini assumes to be right and use them
  427.     instead. Please NOTE: Gemini DOESN'T WORK in any 2 or 4 colours mode. If a
  428.     user enters these graphic modes, Gemini fill these addresses (+72 to +84)
  429.     with a particular value: -1. You don't have to check the graphic mode specs
  430.     on a mode change. Just call Gemini_SetUpScreen (or _SetUpSprite) as usual.
  431.     If you get, on exit, the -1 value in the previous locations, then warn the
  432.     user that Gemini doesn't work in this mode and close all the windows you
  433.     need (or fill them with a dummy background or use ChangeFSI to convert the
  434.     last image Gemini produces in one suitable for that graphic mode).
  435. In anycase don't call Gemini_Render while in a "wrong" graphic mode, as the
  436. result will be unpredictable.
  437.  
  438.  
  439.  
  440.  
  441. And, (at last!), the call to render all the scene on the specify output stream
  442. (video or memory) in the specified size...
  443.  
  444. SYS"Gemini_Render"
  445. ------------------
  446. R0 = TMmemoryblock
  447. R1 = TMviewblock
  448. R2 = TMcolourblock
  449. R3 = screen bank to use (1 or 2; 1 for default)
  450. R4 = mode
  451.  
  452. Gemini enables you to have a full double buffering for smooth animation. Just
  453. redraw the screen with R3 set to 1 or 2 alternatively. (see later)
  454. The R4 register contains the mode word. These are the actual defined bits:
  455.  
  456.  Bit   Meaning if set   [meaning if not set]
  457. --------------------------------------------------------------------------
  458.    0  | Colour [grey-shade]
  459.    1  | Wireframe
  460.    2  | Flat shading
  461.    3  | Gouraud shading
  462.    4  | Phong shading
  463.    5  | Transparency enabled  [always opaque]
  464.    6  | Texture mapping enabled
  465.    7  | Chrome  mapping enabled
  466.    8  | Bump    mapping enabled
  467.  9-11 | reserved - set to 0
  468.    12 | draw primitives [don't draw them]
  469.    13 | reserved - set to 0
  470.    14 | perspective view [axonometric view]
  471.    15 | normal navigation mode [VR mode: objects behind observer aren't drawn]
  472.    16 | visualize axes [don't]
  473.    17 | recalculate active plane while rotating [don't]
  474.    18 | remove objects with normals against the current view vector [draw all]
  475.    19 | test ESC key to stop redraw [don't]
  476.    20 | fog activated [fog disabled]
  477.    21 | reserved - set to 0
  478.    22 | recalculate light reflections if you aren't in Phong mode [don't]
  479.    23 | clear the workarea with the current background colour [draw just objects]
  480.    24 | draw bezier-curves/surfaces' visual-hull lines [don't]
  481.    25 | draw polygons' vertices   [don't]
  482.    26 | draw control points       [don't]
  483.    27 | enable lens-flares        [don't]
  484.    28 | show grid points          [don't]       ---> not activated yet
  485.    29 | visualise lights position [don't]
  486. 30-31 | reserved - set to 0
  487.  
  488. Please note: bits 1-4 are mutually exclusive; you should set just one of these.
  489.              Nevertheless you can set Flat+Gouraud+Phong shading (so bits 2-4=%111)
  490.              to obtain the radiosity view-mode. But at the moment it is for internal
  491.              use only.
  492.  
  493.  
  494.  
  495.  
  496. Then there are another two calls, to enable screen buffering
  497.  
  498. SYS"Gemini_StartBuffering"
  499. --------------------------
  500. R1 = TMviewblock
  501.  
  502. This tries to reserve enough video memory to obtain a second bank to enable
  503. screen banking for smooth animations. If it hits the goal, then it copies the
  504. first page into the second, to enable a bank switching also from desktop (the
  505. second page isn't filled with strange colours this way...). Otherwise nothing
  506. happens and Gemini will use the current video memory.
  507.  
  508. SYS"Gemini_EndBuffering"
  509. ------------------------
  510. R1 = TMviewblock
  511.  
  512. This ends the bank switching, releasing (if any) the reserved memory and
  513. copying the contents of the second page (if the current page is the second)
  514. into the first.
  515.  
  516. So, to have a working engine with bank switching do this:
  517. "Gemini_StartBuffering":bank%=1
  518. REPEAT
  519.   bank%=bank%EOR3:"Gemini_Render",... ,... ,... ,bank% ,...
  520. UNTIL end
  521. "Gemini_EndBuffering"
  522.  
  523. this work also if there isn't enough memory for bank switching.
  524.  
  525.  
  526.  
  527.  
  528. Operations over loaded objects
  529. ==============================
  530. SYS"Gemini_Transform"
  531. ---------------------
  532. This call allows you to move/rotate/scale objects. It works over selected objects (so
  533. you first have to select something) but it can affect numbered groups only (both
  534. selected or unselected).
  535. R0 = TMmemoryblock
  536. R2 = objects to alter:
  537.      0 --> modify selected objects (you have to select something first)
  538.      n --> logical number of the group to be modified (no need to select it)
  539. R4 = reason code:
  540.      0 --> translate objects/group
  541.      1 --> scale objects/group
  542.      2 --> transform objects/group using a general transformation matrix
  543. R5 = memory block filled with geometric datas for the operation (all the values are
  544.      multiplied by 2^17, i.e.: original value=0.5, value to store=0.5*2^17):
  545.  
  546. offset |  translate                |      scale       |         general transform
  547. -------|---------------------------|------------------|-------------------------------------------
  548. +0     | amount to add to X coord. | X coord. of the point around which the operation takes place
  549. +4     | amount to add to Y coord. | Y coord. of the point around which the operation takes place
  550. +8     | amount to add to Z coord. | Z coord. of the point around which the operation takes place
  551. +12    |     -                     | X scale factor   | A11 component of the transformation matrix
  552. +16    |     -                     | Y scale factor   | A21
  553. +20    |     -                     | Z scale factor   | A31
  554. +24    |     -                     |     -            |     A12
  555. +28    |     -                     |     -            |     A22
  556. +32    |     -                     |     -            |     A32
  557. +36    |     -                     |     -            |         A13
  558. +40    |     -                     |     -            |         A23
  559. +44    |     -                     |     -            |         A33
  560. +48    |     -                     |     -            | amount to add to X coord.
  561. +52    |     -                     |     -            | amount to add to Y coord.
  562. +56    |     -                     |     -            | amount to add to Z coord.
  563.  
  564. The general transformation acts as follows: first of all the object is modified accordingly to
  565. the 3x3 matrix (around the specified point), then it is translated by the amount specified in
  566. (+48,+52,+56)
  567.  
  568.  
  569.  
  570.  
  571. SYS"Gemini_Select"
  572. ------------------
  573. This is a multi-purpose selection command.
  574. Its behaviour depends upon the reason code passed in R4, as follow:
  575.  
  576. R4 values  | action taken
  577. -----------|-------------------------------------------------------------------
  578.     1      |  Select       all/only visible objects (the ones inside working area)
  579.     2      |  Select       the specified group of objects
  580.     3      |  Select       all the points inside the specified rectangle
  581.     4      |  Find         the point closest to the passed (X,Y) screen coordinates
  582.     6      |  Find         the primitive closest to the passed (X,Y) screen coordinates
  583.     16     |  Deselect     all/only visible objects
  584.     17     |  Deselect     the specified group of objects
  585.     18     |  Deselect     all the points inside the specified rectangle
  586.  
  587.  
  588. SYS"Gemini_Select" R4=6
  589. -----------------------
  590. R0 = TMmemoryblock
  591. R1 = X (OS-Units relative to the whole screen, eg.: X mouse coordinate)
  592. R2 = Y (as above)
  593. R3 = flag: if bit0 is set, then Gemini will check only visible primitives
  594. R4 = 6
  595.  
  596. The other calls aren't implemented yet
  597.  
  598.  
  599.  
  600.  
  601. MISC
  602. ====
  603. SYS"Gemini_readVRML"
  604. --------------------
  605. This call loads a VRML 1.1 file whose name (completed with its path,
  606. otherwise in the current directory) is given in R6.
  607.  
  608. entry:
  609. R0 = TMmemoryblock
  610. R1 = TMviewblock
  611. R2 = TMcolourblock
  612. R3 = U number of polygons for the sphere
  613. R4 = V number of polygons for the sphere
  614. R5 = Number of sides for cone/cylinder's base
  615. R6 = bits  0-15: number of user-defined materials
  616.             16 : set to resize the scene to a default dimension
  617.             17 : set to triangularize all the polygons (if the scene contains convex polygons)
  618. R7 = pointer to NULL terminated filename of VRML file (with full path)
  619. exit:
  620. R3 = number of created points
  621. R4 = number of created polygons
  622. R5 = number of created user-defined materials
  623.  
  624.  
  625. How to draw the scene in several passes
  626. =======================================
  627. You may need to produce a picture in more than one go, expecially if you want
  628. big resolutions (a 2048*2048 32bpp image, with Zbuffer requires 32Mb free!).
  629. You also may want to draw only a portion of the scene required for example by
  630. a Wimp Redraw Request. I recommend you to use this tecnique only for file or
  631. sprite output, as it slows down the rendering time; anyway it works also
  632. if you specify the workarea using "Gemini_SetUpScreen". The basic idea is quite
  633. similar to the one used by the wimp scrollbars. When you specify the workarea,
  634. Gemini assumes that the origin is placed in the top left corner, and the Y
  635. coordinate is positive downwards. To place the origin at the centre of the work-
  636. area, Gemini simply adds a fixed amount to each coordinate. These amounts are
  637. the centre of the scene (in pixel); let's call them (fx,fy). They are stored
  638. in TMviewblock+32 and +36, respectively. These locations are filled each time
  639. you issue a "Gemini_SetUpScreen" or "Gemini_SetUpSprite" call. (fx,fy) are set
  640. to the centre of the currently specified workarea on exit (i.e. if you specify
  641. a workarea of (20,20,120,120) OS-Units (with a X and Y scale factor of 2), on
  642. exit from Gemini_SetUpS... you get (fx,fy)=(25,25), as the workarea is 50x50).
  643. Let's create a 600x384 pixels image, using 3 strips of 600x128 pixels each.
  644. Let's take a scale factor of 2 on both X and Y (eg. MODE28).
  645. Please note: produce strips starting from the top left one to the bottom
  646. righ. In the following example I consider only 3 horizontal strips, but
  647. once you have understood how it works, you can redraw any portion inside the
  648. "main" (logical) workarea.
  649.  
  650. In OS-Units, here are the 3 workareas to specify:
  651.  
  652.   ________________________________________________________768
  653.   |                                                      |
  654.   |                                                      |
  655.   |                                                      |
  656.   |              Strip #1                                |
  657.   |                                                      |
  658.   |                                                      |
  659.   |                                                      |
  660.   |______________________________________________________|512
  661.   |                                                      |
  662.   |                                                      |
  663.   |                                                      |
  664.   |              Strip #2                                |
  665.   |                                                      |
  666.   |                                                      |
  667.   |                                                      |
  668.   |______________________________________________________|256
  669.   |                                                      |
  670.   |                                                      |
  671.   |                                                      |
  672.   |              Strip #3                                |
  673.   |                                                      |
  674.   |                                                      |
  675.   |______________________________________________________|0
  676.  0                                                   1200
  677.  
  678. So, we have to:
  679. 1) "Gemini_SetUpS..." specifying strip#1
  680. 2)  alter the (fx,fy) settings like using scroll bars (see later)
  681. 3) "Gemini_Render" to draw this strip
  682. 4) "Gemini_SetUpS..." specifying strip#2
  683. 5)  alter the (fx,fy) settings
  684. 6) "Gemini_Render" to draw this strip
  685. 7) "Gemini_SetUpS..." specifying strip#3
  686. 8) alter the (fx,fy) settings
  687. 9) "Gemini_Render" to draw this strip
  688. Each strip, once defined, will have its local coordinate system, starting
  689. from its top-left corner. So, in pixel:
  690.   ________________________________________________________
  691.   |(0,0)                                                 |
  692.   |                                                      |
  693.   |                                                      |
  694.   |              Strip #1                                |
  695.   |                                                      |
  696.   |                                                      |
  697.   |                                            (599,127) |
  698.   |______________________________________________________|
  699.   |(0,0)                                                 |
  700.   |                                                      |
  701.   |                                                      |
  702.   |              Strip #2                                |
  703.   |                                                      |
  704.   |                                                      |
  705.   |                                            (599,127) |
  706.   |______________________________________________________|
  707.   |(0,0)                                                 |
  708.   |                                                      |
  709.   |                                                      |
  710.   |              Strip #3                                |
  711.   |                                                      |
  712.   |                                            (599,127) |
  713.   |______________________________________________________|
  714.  
  715. the centre of the whole scene MUST BE THE SAME for all the strips, considering
  716. their relative positions. In OS-Units, considering the global image, (fx,fy)
  717. IS POSITIONED to the middle of the second strip (600,384), but when you specify
  718. and work inside a strip, you have to translate the global position of the
  719. logical centre (OS-Unit) in the current local coordinate system of the strip
  720. (pixel).
  721. So, the strip#1 MUST have (fx,fy) set manually to (300,192)
  722.     the strip#2 MUST have (fx,fy) set manually to (300, 64)
  723.     the strip#3 MUST have (fx,fy) set manually to (300,-64)
  724.  
  725.    ______________________________________________________
  726.   |(0,0)                |                                |
  727.   |      Strip#1        |                                |
  728.   |                     |                                |
  729.   |                     |128+64                          |
  730.   |                     |                                |
  731.   |                     |                                |
  732.   |                     |                      (599,127) |
  733.   |_____________________|________________________________|
  734.   |(0,0)           |    |                                |
  735.   |      Strip#2   |64  |                                |
  736.   |                |    |                                |
  737.   |       300      |    |                                |
  738.   |<---------------------->. (fx,fy)                     |
  739.   |                   |                                  |
  740.   |                   |                        (599,127) |
  741.   |___________________|__________________________________|
  742.   |(0,0)              |-64                               |
  743.   |      Strip#3                                         |
  744.   |                                                      |
  745.   |                                                      |
  746.   |                                                      |
  747.   |                                            (599,127) |
  748.   |______________________________________________________|
  749.  
  750. We are altering only Y position of each strips, so the fx coordinate is
  751. unchanged, equal to half the Xsize of the total image in pixel (i.e. 300).
  752. In general, to generate a portion of the main image, you have to work out
  753. both the coordinates (fx,fy).
  754.  
  755.  
  756.  
  757.  
  758. Restrictions
  759. ============
  760. 1) Gemini DOESN'T WORK in any 2 or 4 colours mode.
  761. 2) Workarea coordinates are translated into memory addresses for plotting purposes, which
  762.    MUST BE BYTE aligned. This involves just the routine that clears the background, not the
  763.    render routine used for objects. Anyway, even if you don't want to redraw background (bit
  764.    23 of R4 in "Gemini_Render" clear), workarea position is moved, so all the objects inside
  765.    are moved accordingly. In practice, only the X coordinates may be affected from this
  766.    readjustament. In particular, when in a 4bpp mode, X workarea coordinates must be multiple
  767.    of 2 pixels. From 8bpp modes on (and so also 16bpp and 32bpp) there aren't restrictions.
  768. 3) ALL MEMORY LOCATIONS (Points&Primitives workarea, Zbuffer, TMmemoryblock, .... etc.)
  769.    MUST BE WORD ALIGNED!
  770. 4) When drawing to screen, the workarea you specify is always clipped to fit into it:
  771.          ________________                            ________________
  772.         |     screen     |                          |     screen     |
  773.      ___|__________      |                          |__________      |
  774.     |   |          |     |                          |          |     |
  775.     |   |          |     |         ====>>>          | workarea |     |
  776.     |   |          |     |                          |          |     |
  777.     |   |__________|_____|                          |__________|_____|
  778.     | workarea     |
  779.     |______________|
  780.  
  781.  
  782.  
  783.  
  784. TopModel 3D scene
  785. =================
  786. In a TopModel 3Dscene (&139) basically you can find (raw by raw)
  787.  
  788. 3DScene                           | Header
  789. 2.00                              | file version number
  790. 27185169                          | mode as described in "Gemini_Render" (in R4)
  791. 48896                             | min size of points     workarea needed (+58*32 bytes always)
  792. 85056                             | min size of primitives workarea needed
  793. 0                                 | min size of group data needed
  794. 24576                             | min size of mats+cols+textures
  795. 122000                            | min size of a standard RiscOS sprite-area to load the textures used
  796. 256                               | size of the portion of TMviewblock saved
  797. 0                                 | reserved, must be 0
  798. 0                                 | reserved, must be 0
  799. 0                                 | reserved, must be 0
  800. 55232                             | ldm of points workarea when it was saved
  801. 333376                            | ldm of primit.workarea when it was saved
  802. 1680832                           | ldm of texture sprite-area when it was saved
  803.  
  804. Then you find a memory dump of points, primitives and groups workareas,
  805. colours+materials+textures table, spritefile containing the texture and TMviewblock area.
  806.  
  807.  
  808.  
  809.  
  810. TopModel 3D file
  811. ================
  812. In a TopModel 3DFile (&B5C) basically you can find (raw by raw)
  813.  
  814. 3DModel                           | Header
  815. 2.00                              | file version number
  816. View1  0,403520,-63204,[...]      | view infos (optional, may be present or not)
  817. Ambiental  255,255,255, 0         | ambiental light infos    (optional)
  818. Solar  255,255,255,    [...]      | standard sun light infos (optional)
  819. Grid  50,4.0000,4.0000 [...]      | grid infos               (optional)
  820. 127392                            | min size of points     workarea needed (+58*32 bytes always)
  821. 284992                            | min size of primitives workarea needed
  822. 0                                 | min size of group data needed
  823. 3980                              | total number of points and lights
  824. 7124                              | total number pf primitives in the file
  825. 3980                              | number of selected points when saved
  826. 7124                              | number of selected primitives when saved
  827. 0                                 | number of selected groups when saved
  828. 0                                 | number of selected lights when saved
  829. 981456                            | ldm of points workarea when it was saved
  830. 1113392                           | ldm of primit.workarea when it was saved
  831. 1                                 | n^ of textures used
  832. 1 -536870912 ,Materials.ceramic.2 | (text.number) (transparent colour), path
  833. 1 , 1                             | n^ of user defined colours, materials
  834.  Colour1,15658507                 | (colour name),(&BBGGRR00)
  835.  Material1, 194841272,0,0,0,0     | (material name),mat!12,mat!16,mat!20,mat!24,mat!28 (the latter is currently unused)
  836.  
  837. Then the file goes on with a memory dump of the points workarea followed
  838. immediately by a memory dump of the primitives and of the groups workareas.
  839.  
  840.  
  841.  
  842.  
  843. Disclaimer
  844. ==========
  845. The module and this documentation are supplied "as is"; neither Sicronia nor
  846. the author of Gemini make any warranty, whether express or implied, as to the
  847. merchantability of the software or its fitness for any purpose.
  848. In no circumstances will Sincronia or the author of Gemini be liable for
  849. any damage, loss of profits, goodwill or for any indirect or inconsequential
  850. loss arising from the use of this software or of this documentation.
  851. Using Gemini is deemed acceptance of these terms.
  852.