46 |
|
There are two ways to support the language, by linking the parser to |
47 |
|
the program itself, or by linking the parser to a translator program |
48 |
|
that expresses MGF entities in the native scene description format. |
49 |
< |
The differences in the two approaches are slight, and we will explain |
49 |
> |
The differences in the two approaches are slight, and we will mention |
50 |
|
them following a general explanation of the parser and support library. |
51 |
|
|
52 |
|
The Parser |
147 |
|
and the current object name list will be kept in the global array obj_name. |
148 |
|
The number of names is stored in the global obj_nnames variable. To clear |
149 |
|
this array (freeing any memory used in the process), call obj_clear. |
150 |
+ |
|
151 |
+ |
Loading vs. Translating |
152 |
+ |
======================= |
153 |
+ |
As mentioned in the introduction, the parser may be used either to load |
154 |
+ |
data into a rendering program directly, or to get MGF input for translation |
155 |
+ |
to another file format. In either case, the procedure is nearly identical. |
156 |
+ |
The only important difference is what you do with the parser data structures |
157 |
+ |
after loading. For a translator, this is not an issue, but rendering |
158 |
+ |
programs usually need all the memory they can get. Therefore, once the |
159 |
+ |
input process is complete, you should call the mg_clear function to free |
160 |
+ |
the parser data structures and return to an initialized state (i.e. it |
161 |
+ |
is never necessary to recall the mg_init routine). |
162 |
+ |
|
163 |
+ |
Also, if you use some of the support functions, you should call their |
164 |
+ |
specific clearing functions. For the transform module, the call is |
165 |
+ |
xf_clear. For the object support module, the call is obj_clear. The |
166 |
+ |
context routines use the c_clearall function, but this is actually |
167 |
+ |
called by mg_clear, so calling it again is unnecessary. |
168 |
+ |
|
169 |
+ |
Linking Vertices |
170 |
+ |
================ |
171 |
+ |
Although the MGF language was designed with linking vertices in mind, |
172 |
+ |
there are certain aspects which make this goal more challenging. |
173 |
+ |
Specifically, the ability to redefine values for a previously named |
174 |
+ |
vertex is troublesome for the programmer, since the same vertex can |
175 |
+ |
have different values at different points in the input. Likewise, the |
176 |
+ |
effect of the transform entity on surfaces rather than vertices means |
177 |
+ |
that the same named vertex can appear in many positions. |
178 |
+ |
|
179 |
+ |
It is not possible to use the parser data structures directly for |
180 |
+ |
linking vertices, but we've taken a couple of steps in the support |
181 |
+ |
routines to make the task of organizing your own data structures a |
182 |
+ |
little easier. First, there is a clock member in the C_VERTEX |
183 |
+ |
structure that is incremented on each change. (The same member is |
184 |
+ |
contained in the C_COLOR and C_MATERIAL structures.) Second, the |
185 |
+ |
current transform (pointed to by xf_context) contains a unique |
186 |
+ |
identifier, xf_context->xid. This is a long integer that will be |
187 |
+ |
different for each unique transform. (It is actually a hash key on the |
188 |
+ |
transformation matrix, and there is about 1 chance in 2 billion that |
189 |
+ |
two different matrices will hash to the same value. Is this a bug? |
190 |
+ |
I guess it depends on how long the programmer lives -- or vice versa.) |
191 |
+ |
|
192 |
+ |
There are two ways to use of this additional information. One |
193 |
+ |
is to record the vertex clock value along with it's id and the |
194 |
+ |
current xf_context->xid value. If another vertex comes along with |
195 |
+ |
the same name, but one of these two additional values fails to match, |
196 |
+ |
then it (probably) is a different vertex. Alternatively, one can reset |
197 |
+ |
the clock member every time a new vertex is stored. That way, it is |
198 |
+ |
only necessary to check the clock against zero rather than storing this |
199 |
+ |
value along with the vertex name and transform id. If the name and |
200 |
+ |
transform are the same and the clock is zero, then it's the same vertex |
201 |
+ |
as last time. |
202 |
+ |
|
203 |
+ |
Yet another approach is to ignore the parser structures entirely and |
204 |
+ |
focus on the actual vertex values. After all, the user is not compelled |
205 |
+ |
to reuse the same vertex names for the same points. It is just as likely |
206 |
+ |
that the same vertices will appear under different names, so that none |
207 |
+ |
of the above would help to merge them. The most sure-fire approach to |
208 |
+ |
linking identical vertices is therefore to hash the point and normal |
209 |
+ |
values directly and use the functions in lookup.c to associate them. |
210 |
+ |
You will have to write your own hash function, and I recommend making |
211 |
+ |
one that allows a little slop so that nearly identical points hash to |
212 |
+ |
the same value. |
213 |
|
|
214 |
|
Examples |
215 |
|
======== |