1 // Here lies the slow as shit renderer!
2 
3 #ifndef polymer_h_
4 # define polymer_h_
5 
6 # include "baselayer.h"
7 # include "build.h"
8 # include "compat.h"
9 # include "glad/glad.h"
10 # include "glbuild.h"
11 # include "hightile.h"
12 # include "mdsprite.h"
13 # include "osd.h"
14 # include "polymost.h"
15 # include "pragmas.h"
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 #define PR_LINEAR_FOG
22 
23 // CVARS
24 extern int32_t      pr_lighting;
25 extern int32_t      pr_normalmapping;
26 extern int32_t      pr_specularmapping;
27 extern int32_t      pr_shadows;
28 extern int32_t      pr_shadowcount;
29 extern int32_t      pr_shadowdetail;
30 extern int32_t      pr_shadowfiltering;
31 extern int32_t      pr_maxlightpasses;
32 extern int32_t      pr_maxlightpriority;
33 extern int32_t      pr_fov;
34 extern double       pr_customaspect;
35 extern int32_t      pr_billboardingmode;
36 extern int32_t      pr_verbosity;
37 extern int32_t      pr_wireframe;
38 extern int32_t      pr_vbos;
39 extern int32_t      pr_buckets;
40 extern int32_t      pr_gpusmoothing;
41 extern int32_t      pr_overrideparallax;
42 extern float        pr_parallaxscale;
43 extern float        pr_parallaxbias;
44 extern int32_t      pr_overridespecular;
45 extern float        pr_specularpower;
46 extern float        pr_specularfactor;
47 extern int32_t      pr_highpalookups;
48 extern int32_t      pr_artmapping;
49 extern int32_t      pr_overridehud;
50 extern float        pr_hudxadd;
51 extern float        pr_hudyadd;
52 extern float        pr_hudzadd;
53 extern int32_t      pr_hudangadd;
54 extern int32_t      pr_hudfov;
55 extern float        pr_overridemodelscale;
56 extern int32_t      pr_ati_fboworkaround;
57 extern int32_t      pr_ati_nodepthoffset;
58 #ifdef __APPLE__
59 extern int32_t      pr_ati_textureformat_one;
60 #endif
61 extern int32_t      pr_nullrender;
62 
63 extern int32_t      r_pr_maxlightpasses;
64 
65 // MATERIAL
66 typedef enum {
67                     PR_BIT_HEADER,              // must be first
68                     PR_BIT_ANIM_INTERPOLATION,
69                     PR_BIT_LIGHTING_PASS,
70                     PR_BIT_NORMAL_MAP,
71                     PR_BIT_ART_MAP,
72                     PR_BIT_DIFFUSE_MAP,
73                     PR_BIT_DIFFUSE_DETAIL_MAP,
74                     PR_BIT_DIFFUSE_MODULATION,
75                     PR_BIT_DIFFUSE_MAP2,
76                     PR_BIT_HIGHPALOOKUP_MAP,
77                     PR_BIT_SPECULAR_MAP,
78                     PR_BIT_SPECULAR_MATERIAL,
79                     PR_BIT_MIRROR_MAP,
80                     PR_BIT_FOG,
81                     PR_BIT_GLOW_MAP,
82                     PR_BIT_PROJECTION_MAP,
83                     PR_BIT_SHADOW_MAP,
84                     PR_BIT_LIGHT_MAP,
85                     PR_BIT_SPOT_LIGHT,
86                     PR_BIT_POINT_LIGHT,
87                     PR_BIT_FOOTER,              // must be just before last
88                     PR_BIT_COUNT                // must be last
89 }                   prbittype;
90 
91 typedef struct      s_prmaterial {
92     // PR_BIT_ANIM_INTERPOLATION
93     GLfloat         frameprogress;
94     GLfloat*        nextframedata;
95     // PR_BIT_NORMAL_MAP
96     GLuint          normalmap;
97     GLfloat         normalbias[2];
98     GLfloat*        tbn;
99     // PR_BIT_ART_MAP
100     GLuint          artmap;
101     GLuint          basepalmap;
102     GLuint          lookupmap;
103     GLint           shadeoffset;
104     GLfloat         visibility;
105     // PR_BIT_DIFFUSE_MAP
106     GLuint          diffusemap;
107     GLfloat         diffusescale[2];
108     // PR_BIT_HIGHPALOOKUP_MAP
109     GLuint          highpalookupmap;
110     // PR_BIT_DIFFUSE_DETAIL_MAP
111     GLuint          detailmap;
112     GLfloat         detailscale[2];
113     // PR_BIT_DIFFUSE_MODULATION
114     GLubyte         diffusemodulation[4];
115     // PR_BIT_SPECULAR_MAP
116     GLuint          specmap;
117     // PR_BIT_SPECULAR_MATERIAL
118     GLfloat         specmaterial[2];
119     // PR_BIT_MIRROR_MAP
120     GLuint          mirrormap;
121     // PR_BIT_GLOW_MAP
122     GLuint          glowmap;
123     // PR_BIT_SHADOW_MAP
124     GLboolean       mdspritespace;
125 }                   _prmaterial;
126 
127 typedef struct      s_prrograminfo {
128     GLuint          handle;
129     // PR_BIT_ANIM_INTERPOLATION
130     GLint           attrib_nextFrameData;
131     GLint           attrib_nextFrameNormal;
132     GLint           uniform_frameProgress;
133     // PR_BIT_NORMAL_MAP
134     GLint           attrib_T;
135     GLint           attrib_B;
136     GLint           attrib_N;
137     GLint           uniform_eyePosition;
138     GLint           uniform_normalMap;
139     GLint           uniform_normalBias;
140     // PR_BIT_ART_MAP
141     GLuint          uniform_artMap;
142     GLuint          uniform_basePalMap;
143     GLuint          uniform_lookupMap;
144     GLuint          uniform_shadeOffset;
145     GLuint          uniform_visibility;
146     // PR_BIT_DIFFUSE_MAP
147     GLint           uniform_diffuseMap;
148     GLint           uniform_diffuseScale;
149     // PR_BIT_HIGHPALOOKUP_MAP
150     GLuint          uniform_highPalookupMap;
151     // PR_BIT_DIFFUSE_DETAIL_MAP
152     GLint           uniform_detailMap;
153     GLint           uniform_detailScale;
154     // PR_BIT_SPECULAR_MAP
155     GLint           uniform_specMap;
156     // PR_BIT_SPECULAR_MATERIAL
157     GLint           uniform_specMaterial;
158     // PR_BIT_MIRROR_MAP
159     GLint           uniform_mirrorMap;
160 #ifdef PR_LINEAR_FOG
161     // PR_BIT_FOG
162     GLint           uniform_linearFog;
163 #endif
164     // PR_BIT_GLOW_MAP
165     GLint           uniform_glowMap;
166     // PR_BIT_PROJECTION_MAP
167     GLint           uniform_shadowProjMatrix;
168     // PR_BIT_SHADOW_MAP
169     GLint           uniform_shadowMap;
170     // PR_BIT_LIGHT_MAP
171     GLint           uniform_lightMap;
172     // PR_BIT_SPOT_LIGHT
173     GLint           uniform_spotDir;
174     GLint           uniform_spotRadius;
175 }                   _prprograminfo;
176 
177 #define             PR_INFO_LOG_BUFFER_SIZE 8192
178 
179 // Think about changing highPal[Scale|Bias] in the program bit if you change this
180 #define             PR_HIGHPALOOKUP_BIT_DEPTH 6
181 #define             PR_HIGHPALOOKUP_DIM (1 << PR_HIGHPALOOKUP_BIT_DEPTH)
182 #define             PR_HIGHPALOOKUP_DATA_SIZE (4 * PR_HIGHPALOOKUP_DIM * \
183                                                    PR_HIGHPALOOKUP_DIM * \
184                                                    PR_HIGHPALOOKUP_DIM)
185 
186 typedef struct      s_prprogrambit {
187     int32_t         bit;
188     const char*           vert_def;
189     const char*           vert_prog;
190     const char*           frag_def;
191     const char*           frag_prog;
192 }                   _prprogrambit;
193 
194 typedef struct      s_prbucket {
195     // index
196     int16_t         tilenum;
197     char            pal;
198 
199     _prmaterial     material;
200     int32_t         invalidmaterial;
201 
202     // geom indices
203     GLuint*          indices;
204     uint32_t         count;
205     uint32_t         buffersize;
206     GLuint*          indiceoffset;
207 
208     struct s_prbucket* next;
209 }                   _prbucket;
210 
211 #include "prlights.h"
212 
213 // RENDER TARGETS
214 typedef struct      s_prrt {
215     GLenum          target;
216     GLuint          color;
217     GLuint          z;
218     GLuint          fbo;
219     int32_t         xdim, ydim;
220 }                   _prrt;
221 
222 // BUILD DATA
223 
224 typedef struct      s_prvert {
225     GLfloat         x;
226     GLfloat         y;
227     GLfloat         z;
228     GLfloat         u;
229     GLfloat         v;
230     GLubyte         r;
231     GLubyte         g;
232     GLubyte         b;
233     GLubyte         a;
234 }                   _prvert;
235 
236 typedef struct      s_prplane {
237     // geometry
238     _prvert*        buffer;
239     int32_t         vertcount;
240     GLuint          vbo;
241     uint32_t        mapvbo_vertoffset;
242     _prbucket*      bucket;
243     // attributes
244     GLfloat         tbn[3][3];
245     GLfloat         plane[4];
246     _prmaterial     material;
247     // elements
248     GLushort*       indices;
249     int32_t         indicescount;
250     GLuint          ivbo;
251     // lights
252     int16_t         lights[PR_MAXLIGHTS];
253     uint16_t        lightcount;
254 }                   _prplane;
255 
256 typedef struct      s_prsector {
257     // polymer data
258     GLdouble*       verts;
259     _prplane        floor;
260     _prplane        ceil;
261     int16_t         curindice;
262     int32_t         indicescount;
263     int32_t         oldindicescount;
264     // stuff
265     float           wallsproffset;
266     float           floorsproffset;
267     // build sector data
268     int32_t         ceilingz, floorz;
269     uint16_t        ceilingstat, floorstat;
270     int16_t         ceilingpicnum, ceilingheinum;
271     int8_t          ceilingshade;
272     uint8_t         ceilingpal, ceilingxpanning, ceilingypanning;
273     int16_t         floorpicnum, floorheinum;
274     int8_t          floorshade;
275     uint8_t         floorpal, floorxpanning, floorypanning;
276     uint8_t         visibility;
277 
278     int16_t         floorpicnum_anim, ceilingpicnum_anim;
279 
280     struct          {
281         int32_t     empty       : 1;
282         int32_t     uptodate    : 1;
283         int32_t     invalidtex  : 1;
284     }               flags;
285     uint32_t        invalidid;
286     uint32_t        trackedrev;
287 }                   _prsector;
288 
289 typedef struct      s_prwall {
290     _prplane        wall;
291     _prplane        over;
292     _prplane        mask;
293 
294     // stuff
295     GLfloat*        bigportal;
296     //GLfloat*        cap;
297     GLuint          stuffvbo;
298 
299     // build wall data
300     uint16_t        cstat;
301     int16_t         picnum, overpicnum;
302     int8_t          shade;
303     uint8_t         pal, xrepeat, yrepeat, xpanning, ypanning;
304 
305     // nextwall data
306     int16_t         nwallpicnum, nwallcstat;
307     int8_t          nwallxpanning, nwallypanning;
308     int8_t          nwallshade;
309 
310     int16_t         picnum_anim, overpicnum_anim;
311 
312     char            underover;
313     uint32_t        invalidid;
314     struct          {
315         int32_t     empty       : 1;
316         int32_t     uptodate    : 1;
317         int32_t     invalidtex  : 1;
318     }               flags;
319     uint32_t        trackedrev;
320 }                   _prwall;
321 
322 typedef struct      s_prsprite {
323     _prplane        plane;
324     uint32_t        hash;
325 }                   _prsprite;
326 
327 typedef struct      s_prmirror {
328     _prplane        *plane;
329     int16_t         sectnum;
330     int16_t         wallnum;
331     int8_t          rorstat;
332 }                   _prmirror;
333 
334 typedef struct      s_prhighpalookup {
335     char            *data;
336     GLuint          map;
337 }                   _prhighpalookup;
338 
339 typedef void    (*animatespritesptr)(int32_t, int32_t, int32_t, int32_t, int32_t);
340 
341 typedef struct      s_pranimatespritesinfo {
342     animatespritesptr animatesprites;
343     int32_t         x, y, z, a, smoothratio;
344 }                   _pranimatespritesinfo;
345 
346 typedef void    (*rorcallback)(int16_t sectnum, int16_t wallnum, int8_t rorstat, int16_t *msectnum, int32_t *gx, int32_t *gy, int32_t *gz);
347 
348 // this one has to be provided by the application
349 extern void G_Polymer_UnInit(void);
350 
351 // EXTERNAL FUNCTIONS
352 int32_t             polymer_init(void);
353 void                polymer_uninit(void);
354 void                polymer_setaspect(int32_t);
355 void                polymer_glinit(void);
356 void                polymer_resetlights(void);
357 void                polymer_loadboard(void);
358 int32_t             polymer_printtext256(int32_t xpos, int32_t ypos, int16_t col, int16_t backcol, const char *name, char fontsize);
359 void                polymer_fillpolygon(int32_t npoints);
360 void polymer_drawrooms(int32_t daposx, int32_t daposy, int32_t daposz, fix16_t daang, int32_t dahoriz, int16_t dacursectnum);
361 void                polymer_drawmasks(void);
362 void                polymer_editorpick(void);
363 void                polymer_inb4rotatesprite(int16_t tilenum, char pal, int8_t shade, int32_t method);
364 void                polymer_postrotatesprite(void);
365 void                polymer_drawmaskwall(int32_t damaskwallcnt);
366 void                polymer_drawsprite(int32_t snum);
367 void                polymer_setanimatesprites(animatespritesptr animatesprites, int32_t x, int32_t y, int32_t z, int32_t a, int32_t smoothratio);
368 int16_t             polymer_addlight(_prlight* light);
369 void                polymer_deletelight(int16_t lighti);
370 void                polymer_invalidatelights(void);
371 void                polymer_texinvalidate(void);
372 void                polymer_definehighpalookup(char basepalnum, char palnum, char *data);
373 int32_t             polymer_havehighpalookup(int32_t basepalnum, int32_t palnum);
374 void                polymer_setrorcallback(rorcallback callback);
375 
376 
377 extern _prsprite    *prsprites[MAXSPRITES];
polymer_invalidatesprite(int32_t i)378 static inline void polymer_invalidatesprite(int32_t i)
379 {
380     if (prsprites[i])
381         prsprites[i]->hash = 0xDEADBEEF;
382 }
383 
384 extern GLuint       prartmaps[MAXTILES];
polymer_invalidateartmap(int32_t tilenum)385 static inline void polymer_invalidateartmap(int32_t tilenum)
386 {
387     if (prartmaps[tilenum])
388     {
389         glDeleteTextures(1, &prartmaps[tilenum]);
390         prartmaps[tilenum] = 0;
391     }
392 }
393 
394 // Compare with eligible_for_tileshades()
polymer_eligible_for_artmap(int32_t tilenum,const pthtyp * pth)395 static inline int32_t polymer_eligible_for_artmap(int32_t tilenum, const pthtyp *pth)
396 {
397     return ((!pth || !pth->hicr) && tilenum < (MAXTILES - 4));
398 }
399 
400 # ifdef POLYMER_C
401 
402 // CORE
403 static void         polymer_displayrooms(int16_t sectnum);
404 static void         polymer_emptybuckets(void);
405 static _prbucket*   polymer_findbucket(int16_t tilenum, char pal);
406 static void         polymer_bucketplane(_prplane* plane);
407 static void         polymer_drawplane(_prplane* plane);
408 static inline void  polymer_inb4mirror(_prvert* buffer, const GLfloat* plane);
409 static void         polymer_animatesprites(void);
410 static void         polymer_freeboard(void);
411 // SECTORS
412 static int32_t      polymer_initsector(int16_t sectnum);
413 static int32_t      polymer_updatesector(int16_t sectnum);
414 void PR_CALLBACK    polymer_tesserror(GLenum error);
415 void PR_CALLBACK    polymer_tessedgeflag(GLenum error);
416 void PR_CALLBACK    polymer_tessvertex(void* vertex, void* sector);
417 static int32_t      polymer_buildfloor(int16_t sectnum);
418 static void         polymer_drawsector(int16_t sectnum, int32_t domasks);
419 // WALLS
420 static int32_t      polymer_initwall(int16_t wallnum);
421 static void         polymer_updatewall(int16_t wallnum);
422 static void         polymer_drawwall(int16_t sectnum, int16_t wallnum);
423 // HSR
424 static void         polymer_computeplane(_prplane* p);
425 static inline void  polymer_crossproduct(const GLfloat* in_a, const GLfloat* in_b, GLfloat* out);
426 static inline void  polymer_transformpoint(const float* inpos, float* pos, const float* matrix);
427 static inline void  polymer_normalize(float* vec);
428 static inline void  polymer_pokesector(int16_t sectnum);
429 static void         polymer_extractfrustum(GLfloat* modelview, GLfloat* projection, float* frustum);
430 static inline int32_t polymer_planeinfrustum(_prplane *plane, const float* frustum);
431 static inline void  polymer_scansprites(int16_t sectnum, tspriteptr_t tsprite, int32_t* spritesortcnt);
432 static void         polymer_updatesprite(int32_t snum);
433 // SKIES
434 static void         polymer_getsky(void);
435 static void         polymer_drawsky(int16_t tilenum, char palnum, int8_t shade);
436 static void         polymer_initartsky(void);
437 static void         polymer_drawartsky(int16_t tilenum, char palnum, int8_t shade);
438 static void         polymer_drawartskyquad(int32_t p1, int32_t p2, GLfloat height);
439 static void         polymer_drawskybox(int16_t tilenum, char palnum, int8_t shade);
440 // MDSPRITES
441 static void         polymer_drawmdsprite(tspriteptr_t tspr);
442 static void         polymer_loadmodelvbos(md3model_t* m);
443 // MATERIALS
444 static void         polymer_getscratchmaterial(_prmaterial* material);
445 static _prbucket*   polymer_getbuildmaterial(_prmaterial* material, int16_t tilenum, char pal, int8_t shade, int8_t vis, int32_t cmeth);
446 static int32_t      polymer_bindmaterial(const _prmaterial *material, const int16_t* lights, int lightcount);
447 static void         polymer_unbindmaterial(int32_t programbits);
448 static void         polymer_compileprogram(int32_t programbits);
449 // LIGHTS
450 static void         polymer_removelight(int16_t lighti);
451 static void         polymer_updatelights(void);
452 static inline void  polymer_resetplanelights(_prplane* plane);
453 static void         polymer_addplanelight(_prplane* plane, int16_t lighti);
454 static inline void  polymer_deleteplanelight(_prplane* plane, int16_t lighti);
455 static int32_t      polymer_planeinlight(_prplane* plane, _prlight* light);
456 static void         polymer_invalidateplanelights(_prplane* plane);
457 static void         polymer_invalidatesectorlights(int16_t sectnum);
458 static void         polymer_processspotlight(_prlight* light);
459 static inline void  polymer_culllight(int16_t lighti);
460 static void         polymer_prepareshadows(void);
461 // RENDER TARGETS
462 static void         polymer_initrendertargets(int32_t count);
463 // DEBUG OUTPUT
464 void PR_CALLBACK    polymer_debugoutputcallback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
465 
466 #define INDICE(n) ((p->indices) ? (p->indices[(i+n)%p->indicescount]) : (((i+n)%p->vertcount)))
467 
468 #define SWITCH_CULL_DIRECTION { culledface = (culledface == GL_FRONT) ? GL_BACK : GL_FRONT; glCullFace(culledface); }
469 
dot2f(const GLfloat * v1,const GLfloat * v2)470 static inline GLfloat dot2f(const GLfloat *v1, const GLfloat *v2)
471 {
472     return v1[0]*v2[0] + v1[1]*v2[1];
473 }
474 
dot3f(const GLfloat * v1,const GLfloat * v2)475 static inline GLfloat dot3f(const GLfloat *v1, const GLfloat *v2)
476 {
477     return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
478 }
479 
relvec2f(const GLfloat * v1,const GLfloat * v2,GLfloat * out)480 static inline void relvec2f(const GLfloat *v1, const GLfloat *v2, GLfloat *out)
481 {
482     out[0] = v2[0]-v1[0];
483     out[1] = v2[1]-v1[1];
484 }
485 
486 // the following from gle/vvector.h
487 
488 /* ========================================================== */
489 /* determinant of matrix
490  *
491  * Computes determinant of matrix m, returning d
492  */
493 
494 #define DETERMINANT_3X3(d,m)                    \
495 {                                \
496    d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]);        \
497    d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]);    \
498    d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]);    \
499 }
500 
501 /* ========================================================== */
502 /* i,j,th cofactor of a 4x4 matrix
503  *
504  */
505 
506 #define COFACTOR_4X4_IJ(fac,m,i,j)                 \
507 {                                \
508    int ii[4], jj[4], k;                        \
509                                 \
510    /* compute which row, columnt to skip */            \
511    for (k=0; k<i; k++) ii[k] = k;                \
512    for (k=i; k<3; k++) ii[k] = k+1;                \
513    for (k=0; k<j; k++) jj[k] = k;                \
514    for (k=j; k<3; k++) jj[k] = k+1;                \
515                                 \
516    (fac) = m[ii[0]][jj[0]] * (m[ii[1]][jj[1]]*m[ii[2]][jj[2]]     \
517                             - m[ii[1]][jj[2]]*m[ii[2]][jj[1]]); \
518    (fac) -= m[ii[0]][jj[1]] * (m[ii[1]][jj[0]]*m[ii[2]][jj[2]]    \
519                              - m[ii[1]][jj[2]]*m[ii[2]][jj[0]]);\
520    (fac) += m[ii[0]][jj[2]] * (m[ii[1]][jj[0]]*m[ii[2]][jj[1]]    \
521                              - m[ii[1]][jj[1]]*m[ii[2]][jj[0]]);\
522                                 \
523    /* compute sign */                        \
524    k = i+j;                            \
525    if ( k != (k/2)*2) {                        \
526       (fac) = -(fac);                        \
527    }                                \
528 }
529 
530 /* ========================================================== */
531 /* determinant of matrix
532  *
533  * Computes determinant of matrix m, returning d
534  */
535 
536 #define DETERMINANT_4X4(d,m)                    \
537 {                                \
538    double cofac;                        \
539    COFACTOR_4X4_IJ (cofac, m, 0, 0);                \
540    d = m[0][0] * cofac;                        \
541    COFACTOR_4X4_IJ (cofac, m, 0, 1);                \
542    d += m[0][1] * cofac;                    \
543    COFACTOR_4X4_IJ (cofac, m, 0, 2);                \
544    d += m[0][2] * cofac;                    \
545    COFACTOR_4X4_IJ (cofac, m, 0, 3);                \
546    d += m[0][3] * cofac;                    \
547 }
548 
549 /* ========================================================== */
550 /* compute adjoint of matrix and scale
551  *
552  * Computes adjoint of matrix m, scales it by s, returning a
553  */
554 
555 #define SCALE_ADJOINT_3X3(a,s,m)                \
556 {                                \
557    a[0][0] = (s) * (m[1][1] * m[2][2] - m[1][2] * m[2][1]);    \
558    a[1][0] = (s) * (m[1][2] * m[2][0] - m[1][0] * m[2][2]);    \
559    a[2][0] = (s) * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);    \
560                                 \
561    a[0][1] = (s) * (m[0][2] * m[2][1] - m[0][1] * m[2][2]);    \
562    a[1][1] = (s) * (m[0][0] * m[2][2] - m[0][2] * m[2][0]);    \
563    a[2][1] = (s) * (m[0][1] * m[2][0] - m[0][0] * m[2][1]);    \
564                                 \
565    a[0][2] = (s) * (m[0][1] * m[1][2] - m[0][2] * m[1][1]);    \
566    a[1][2] = (s) * (m[0][2] * m[1][0] - m[0][0] * m[1][2]);    \
567    a[2][2] = (s) * (m[0][0] * m[1][1] - m[0][1] * m[1][0]);    \
568 }
569 
570 /* ========================================================== */
571 /* compute adjoint of matrix and scale
572  *
573  * Computes adjoint of matrix m, scales it by s, returning a
574  */
575 
576 #define SCALE_ADJOINT_4X4(a,s,m)                \
577 {                                \
578    int i,j;                            \
579                                 \
580    for (i=0; i<4; i++) {                    \
581       for (j=0; j<4; j++) {                    \
582          COFACTOR_4X4_IJ (a[j][i], m, i, j);            \
583          a[j][i] *= s;                        \
584       }                                \
585    }                                \
586 }
587 
588 /* ========================================================== */
589 /* inverse of matrix
590  *
591  * Compute inverse of matrix a, returning determinant m and
592  * inverse b
593  */
594 
595 #define INVERT_3X3(b,det,a)            \
596 {                        \
597    double tmp;                    \
598    DETERMINANT_3X3 (det, a);            \
599    tmp = 1.0 / (det);                \
600    SCALE_ADJOINT_3X3 (b, tmp, a);        \
601 }
602 
603 /* ========================================================== */
604 /* inverse of matrix
605  *
606  * Compute inverse of matrix a, returning determinant m and
607  * inverse b
608  */
609 
610 #define INVERT_4X4(b,det,a)            \
611 {                        \
612    double tmp;                    \
613    DETERMINANT_4X4 (det, a);            \
614    tmp = 1.0 / (det);                \
615    SCALE_ADJOINT_4X4 (b, tmp, a);        \
616 }
617 
618 # endif // !POLYMER_C
619 
620 #ifdef __cplusplus
621 }
622 #endif
623 
624 #endif // !polymer_h_
625