--- ray/src/cv/mgflib/readme.txt 1994/06/25 10:51:36 1.2 +++ ray/src/cv/mgflib/readme.txt 1994/09/01 09:50:27 1.5 @@ -46,7 +46,7 @@ not QUITE that simple, but close.) There are two ways to support the language, by linking the parser to the program itself, or by linking the parser to a translator program that expresses MGF entities in the native scene description format. -The differences in the two approaches are slight, and we will explain +The differences in the two approaches are slight, and we will mention them following a general explanation of the parser and support library. The Parser @@ -63,7 +63,7 @@ some of them in the following sections. Initializing the parser is the most important part of writing an MGF program, and it is done through the mg_ehand array and a call to mg_init. The global mg_ehand variable is an array of pointers to entity handler -functions. The arguments to these functions is always the same, an +functions. The arguments to these functions are always the same, an argument count and an array of argument pointers (ala main). The return value for these integer functions is one of the error codes defined in parser.h, or MG_OK if the entity was handled correctly. You must @@ -107,8 +107,23 @@ to c_hmaterial. Then, whenever a material is needed, c_cmaterial variable will be pointing to a structure with all the current settings. (Note that you would have to also set the color mg_ehand entries to c_hcolor if you intended to support color -materials.) +materials.) A list of related mg_ehand assignments is given below: + mg_ehand[MG_E_COLOR] = c_hcolor; + mg_ehand[MG_E_CMIX] = c_hcolor; + mg_ehand[MG_E_CSPEC] = c_hcolor; + mg_ehand[MG_E_CXY] = c_hcolor; + mg_ehand[MG_E_ED] = c_hmaterial; + mg_ehand[MG_E_MATERIAL] = c_hmaterial; + mg_ehand[MG_E_NORMAL] = c_hvertex; + mg_ehand[MG_E_POINT] = c_hvertex; + mg_ehand[MG_E_RD] = c_hmaterial; + mg_ehand[MG_E_RS] = c_hmaterial; + mg_ehand[MG_E_SIDES] = c_hmaterial; + mg_ehand[MG_E_TD] = c_hmaterial; + mg_ehand[MG_E_TS] = c_hmaterial; + mg_ehand[MG_E_VERTEX] = c_hvertex; + In addition to the three handler functions, context.c contains a few support routines that make life simpler. For vertices, there is the c_getvertex call, which returns a pointer to a named vertex @@ -121,7 +136,7 @@ coordinates). Also, there is a function called c_isgr simply returns 1 or 0 based on whether the passed color structure is close to grey or not. Finally, there is the c_clearall routine, which clears and frees all context data structures, and is the -principle action of the parser's mg_clear function. +principal action of the parser's mg_clear function. Transform Support ================= @@ -148,6 +163,69 @@ and the current object name list will be kept in the g The number of names is stored in the global obj_nnames variable. To clear this array (freeing any memory used in the process), call obj_clear. +Loading vs. Translating +======================= +As mentioned in the introduction, the parser may be used either to load +data into a rendering program directly, or to get MGF input for translation +to another file format. In either case, the procedure is nearly identical. +The only important difference is what you do with the parser data structures +after loading. For a translator, this is not an issue, but rendering +programs usually need all the memory they can get. Therefore, once the +input process is complete, you should call the mg_clear function to free +the parser data structures and return to an initialized state (i.e. it +is never necessary to recall the mg_init routine). + +Also, if you use some of the support functions, you should call their +specific clearing functions. For the transform module, the call is +xf_clear. For the object support module, the call is obj_clear. The +context routines use the c_clearall function, but this is actually +called by mg_clear, so calling it again is unnecessary. + +Linking Vertices +================ +Although the MGF language was designed with linking vertices in mind, +there are certain aspects which make this goal more challenging. +Specifically, the ability to redefine values for a previously named +vertex is troublesome for the programmer, since the same vertex can +have different values at different points in the input. Likewise, the +effect of the transform entity on surfaces rather than vertices means +that the same named vertex can appear in many positions. + +It is not possible to use the parser data structures directly for +linking vertices, but we've taken a couple of steps in the support +routines to make the task of organizing your own data structures a +little easier. First, there is a clock member in the C_VERTEX +structure that is incremented on each change. (The same member is +contained in the C_COLOR and C_MATERIAL structures.) Second, the +current transform (pointed to by xf_context) contains a unique +identifier, xf_context->xid. This is a long integer that will be +different for each unique transform. (It is actually a hash key on the +transformation matrix, and there is about 1 chance in 2 billion that +two different matrices will hash to the same value. Is this a bug? +I guess it depends on how long the programmer lives -- or vice versa.) + +There are two ways to use of this additional information. One +is to record the vertex clock value along with it's id and the +current xf_context->xid value. If another vertex comes along with +the same name, but one of these two additional values fails to match, +then it (probably) is a different vertex. Alternatively, one can reset +the clock member every time a new vertex is stored. That way, it is +only necessary to check the clock against zero rather than storing this +value along with the vertex name and transform id. If the name and +transform are the same and the clock is zero, then it's the same vertex +as last time. + +Yet another approach is to ignore the parser structures entirely and +focus on the actual vertex values. After all, the user is not compelled +to reuse the same vertex names for the same points. It is just as likely +that the same vertices will appear under different names, so that none +of the above would help to merge them. The most sure-fire approach to +linking identical vertices is therefore to hash the point and normal +values directly and use the functions in lookup.c to associate them. +You will have to write your own hash function, and we recommend making +one that allows a little slop so that nearly identical points hash to +the same value. + Examples ======== Two example translator programs are included with this package. @@ -176,9 +254,9 @@ At this point, the legal issues related to this parser worked out. The intent is to offer it free of charge to all those who wish to use it (with no guarantees, of course). However, we may decide that copyright protections are necessary to prevent unauthorized versions -of the parser that do not properly support the MGF standard from getting -spread around. Since this is a pre-release, we trust that you will not -share it with anyone without getting our permission first. +of the parser, which do not properly support the MGF standard, from +getting spread around. Since this is a pre-release, we trust that you +will not share it with anyone without getting our permission first. Questions =========