source: golgotha/src/maxtool/sdk_inc/patch.h @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
  • Property svn:keywords set to Id
File size: 18.6 KB
Line 
1/**********************************************************************
2 *<
3        FILE: patch.h
4
5        DESCRIPTION: Main include file for bezier patches
6
7        CREATED BY: Tom Hudson
8
9        HISTORY: Created June 21, 1995
10
11 *>     Copyright (c) 1995, All Rights Reserved.
12 **********************************************************************/
13
14#ifndef _PATCH_H_
15
16#define _PATCH_H_
17
18#include "mesh.h"
19#include <hitdata.h>
20
21// Handy-dandy integer table class
22typedef Tab<int> IntTab;
23
24// Value for undefined patches and vertices
25#define PATCH_UNDEFINED -1
26
27#define MULTI_PROCESSING        TRUE            // TRUE turns on mp vertex transformation
28
29class ISave;
30class ILoad;
31class PatchMesh;
32
33#define NEWPATCH
34
35#ifdef MAYBE
36class RNormal {
37        public:
38                RNormal()       { smGroup = mtlIndex = 0; }
39                void            setNormal(const Point3 &nor) { normal = nor; }
40                void            addNormal(const Point3 &nor) { normal += nor; }
41                void            normalize(void)         { normal = Normalize(normal); }
42                Point3 &        getNormal(void)         { return normal; }
43                void            setSmGroup(DWORD g)     { smGroup = g; }
44                void            addSmGroup(DWORD g) { smGroup |= g; }
45                DWORD           getSmGroup(void)        { return smGroup; }
46                void            setMtlIndex(DWORD i){ mtlIndex = i; }
47                DWORD           getMtlIndex(void)       { return mtlIndex; }
48                void            setRGB(Point3 &clr)     { rgb = clr; };
49                Point3 &        getRGB(void)            { return rgb; }
50               
51        private:       
52                Point3          normal;   
53                DWORD           smGroup;   
54                DWORD           mtlIndex;   
55                Point3          rgb;       
56        };                                         
57
58#endif // MAYBE
59
60// PRVertex flags: contain clip flags, number of normals at the vertex
61// and the number of normals that have already been rendered.
62// fine PLANE_MASK      0x00003f00UL -- now in gfx.h
63#define NORCT_MASK                      0x000000ffUL
64#define SPECIFIED_NORMAL        0x00004000UL
65#define OUT_LEFT                        0x00010000UL
66#define OUT_RIGHT                       0x00020000UL
67#define OUT_TOP                         0x00040000UL
68#define OUT_BOTTOM                      0x00080000UL
69#define RECT_MASK                       0x000f0000UL
70#define RND_MASK                        0xfff00000UL
71#define RND_NOR0                        0x00100000UL
72#define RND_NOR(n)              (RND_NOR0 << (n))
73
74class PRVertex {
75        public:
76                PRVertex()      { rFlags = 0; /*ern = NULL;*/ }
77                DllExport ~PRVertex(); 
78
79                DWORD           rFlags;     
80                union {
81                        int             iPos[3];       
82                        float   fPos[3];
83                        };
84//              RNormal         rn;               
85//              RNormal         *ern;           
86        };                                       
87
88// Patch vector flags
89#define PVEC_INTERIOR   (1<<0)
90
91// Patch vectors
92
93class PatchVec {
94        public:
95                Point3 p;                       // Location
96                int vert;                       // Vertex which owns this vector
97                int patches[2];         // Patches using this vector
98                DWORD flags;
99                PatchVec() { p = Point3(0,0,0); vert = -1; patches[0] = patches[1] = -1; flags = 0; }
100                DllExport PatchVec(PatchVec &from);
101                void ResetData() { vert = patches[0] = patches[1] = PATCH_UNDEFINED; }
102                DllExport BOOL AddPatch(int index);
103                DllExport PatchVec& operator=(PatchVec& from);
104
105                DllExport IOResult Save(ISave* isave);
106                DllExport IOResult Load(ILoad* iload);
107        };
108
109// Patch vertex flags
110#define PVERT_COPLANAR (1<<0)
111
112// Patch vertex
113
114class PatchVert {
115        public:
116                Point3 p;                       // Location
117                IntTab vectors;         // List of vectors attached to this vertex
118                IntTab patches;         // List of patches using this vertex
119                DWORD flags;
120                PatchVert() { p = Point3(0,0,0); flags = 0; }
121                DllExport PatchVert(PatchVert &from);
122                ~PatchVert() { ResetData(); }
123                DllExport PatchVert& operator=(PatchVert& from);
124                void ResetData() { vectors.Delete(0,vectors.Count()); patches.Delete(0,patches.Count()); }
125                DllExport int FindVector(int index);
126                DllExport void AddVector(int index);
127                DllExport void DeleteVector(int index);
128                DllExport int FindPatch(int index);
129                DllExport void AddPatch(int index);
130                DllExport void DeletePatch(int index);
131
132                DllExport IOResult Save(ISave* isave);
133                DllExport IOResult Load(ILoad* iload);
134        };
135
136class PatchEdge {
137        public:
138                int v1;         // Index of first vertex
139                int vec12;      // Vector from v1 to v2
140                int vec21;      // Vector from v2 to v1
141                int v2;         // Index of second vertex
142                int patch1;     // Index of first patch
143                int patch2;     // Index of second patch
144                PatchEdge() { v1=v2=vec12=vec21=patch1=patch2 = -1; }
145                DllExport PatchEdge(PatchEdge &from);
146                DllExport PatchEdge(int v1, int vec12, int vec21, int v2, int p1, int p2);
147                // Dump the patch edge structure via DebugPrints
148                DllExport void Dump();
149        };
150
151// Patch types
152
153#define PATCH_UNDEF     0       // Undefined (watch out!)
154#define PATCH_TRI       3       // Triangular patch
155#define PATCH_QUAD      4       // Quadrilateral patch
156
157// Patch Flags:
158#define PATCH_AUTO                      (1<<0)  // Interior verts computed automatically if set
159
160class Patch {   
161        public:
162                int type;                       // See types, above
163                int     v[4];                   // Can have three or four vertices
164                int     vec[8];                 // Can have six or eight vector points
165                int     interior[4];    // Can have one or four interior vertices
166                Point3 aux[9];          // Used for triangular patches only -- Degree 4 control points
167                int     adjacent[4];    // Adjacent patches -- Can have three or four
168                int     edge[4];                // Pointers into edge list -- Can have three or four
169                DWORD   smGroup;        // Defaults to 1 -- All patches smoothed in a PatchMesh
170                DWORD   flags;          // See flags, above
171
172                DllExport Patch();      // WARNING: This does not allocate arrays -- Use SetType(type) or Patch(type)
173                DllExport Patch(int type);
174                DllExport Patch(Patch& fromPatch);
175                DllExport ~Patch();
176                DllExport void Init();
177                void    setVerts(int *vrt) { memcpy(v, vrt, type * sizeof(int)); }
178                void    setVerts(int a, int b, int c)  { assert(type == PATCH_TRI); v[0]=a; v[1]=b; v[2]=c; }
179                void    setVerts(int a, int b, int c, int d)  { assert(type == PATCH_QUAD); v[0]=a; v[1]=b; v[2]=c; v[3]=d; }
180                void    setVecs(int ab, int ba, int bc, int cb, int ca, int ac) {
181                        assert(type == PATCH_TRI);
182                        vec[0]=ab; vec[1]=ba; vec[2]=bc; vec[3]=cb; vec[4]=ca; vec[5]=ac;
183                        }
184                void    setVecs(int ab, int ba, int bc, int cb, int cd, int dc, int da, int ad) {
185                        assert(type == PATCH_QUAD);
186                        vec[0]=ab; vec[1]=ba; vec[2]=bc; vec[3]=cb; vec[4]=cd; vec[5]=dc; vec[6]=da, vec[7]=ad;
187                        }
188                void    setInteriors(int a, int b, int c) {
189                        assert(type == PATCH_TRI);
190                        interior[0]=a; interior[1]=b; interior[2]=c;
191                        }
192                void    setInteriors(int a, int b, int c, int d) {
193                        assert(type == PATCH_QUAD);
194                        interior[0]=a; interior[1]=b; interior[2]=c; interior[3]=d;
195                        }
196                int             getVert(int index)      { return v[index]; }
197                int *   getAllVerts(void)       { return v; }
198                DllExport Point3 interp(PatchMesh *pMesh, float u, float v);                    // Quadrilateral
199                DllExport Point3 interp(PatchMesh *pMesh, float u, float v, float w);   // Triangle
200                DllExport void ComputeAux(PatchMesh *pMesh, int index);
201                DllExport void computeInteriors(PatchMesh* pMesh);
202                DllExport void SetType(int type, BOOL init = FALSE);
203                DllExport Patch& operator=(Patch& from);
204                DllExport void SetAuto(BOOL sw = TRUE);
205                BOOL IsAuto() { return (flags & PATCH_AUTO) ? TRUE : FALSE; }
206                // Dump the patch mesh structure via DebugPrints
207                DllExport void Dump();
208
209                DllExport IOResult Save(ISave* isave);
210                DllExport IOResult Load(ILoad* iload);
211        };
212
213// Separate class for patch texture verts
214class TVPatch {
215        public:
216                int     tv[4];                  // Texture verts (always 4 here, even for tri patches)
217                DllExport TVPatch();
218                DllExport TVPatch(TVPatch& fromPatch);
219                DllExport void Init();
220                DllExport void setTVerts(int *vrt, int count);
221                DllExport void setTVerts(int a, int b, int c, int d = 0);
222                int             getTVert(int index)     { return tv[index]; }
223                int *   getAllTVerts(void)      { return tv; }
224                DllExport TVPatch& operator=(TVPatch& from);
225
226                DllExport IOResult Save(ISave* isave);
227                DllExport IOResult Load(ILoad* iload);
228        };
229
230
231// Flag definitions
232#define COMP_TRANSFORM  0x0001  // forces recalc of model->screen transform; else will attempt to use cache
233#define COMP_IGN_RECT   0x0002  // forces all polys to be rendered; else only those intersecting the box will be
234#define COMP_LIGHTING   0x0004  // forces re-lighting of all verts (as when a light moves); else only relight moved verts
235
236#define COMP_ALL                0x00ff
237
238// If this bit is set then the node being displayed by this mesh is selected.
239// Certain display flags only activate when this bit is set.
240#define COMP_OBJSELECTED        (1<<8)
241#define COMP_OBJFROZEN          (1<<9)
242
243typedef int (*INTRFUNC)();
244
245DllExport void setPatchIntrFunc(INTRFUNC fn);
246
247// Special types for patch vertex hits -- Allows us to distinguish what they hit on a pick
248#define PATCH_HIT_PATCH         0
249#define PATCH_HIT_EDGE          1
250#define PATCH_HIT_VERTEX        2
251#define PATCH_HIT_VECTOR        3
252#define PATCH_HIT_INTERIOR      4
253
254class PatchSubHitRec {
255        private:               
256                PatchSubHitRec *next;
257        public:
258                DWORD   dist;
259                PatchMesh *patch;
260                int             index;
261                int             type;
262
263                PatchSubHitRec( DWORD dist, PatchMesh *patch, int index, int type, PatchSubHitRec *next )
264                        { this->dist = dist; this->patch = patch; this->index = index; this->type = type; this->next = next; }
265
266                PatchSubHitRec *Next() { return next; }         
267        };
268
269class SubPatchHitList {
270        private:
271                PatchSubHitRec *first;
272        public:
273                SubPatchHitList() { first = NULL; }
274                ~SubPatchHitList() {
275                        PatchSubHitRec *ptr = first, *fptr;
276                        while ( ptr ) {
277                                fptr = ptr;
278                                ptr = ptr->Next();
279                                delete fptr;
280                                }
281                        first = NULL;
282                        }       
283
284                PatchSubHitRec *First() { return first; }
285                void AddHit( DWORD dist, PatchMesh *patch, int index, int type ) {
286                        first = new PatchSubHitRec(dist,patch,index,type,first);
287                        }
288        };
289
290
291// Special storage class for hit records so we can know which object was hit
292class PatchHitData : public HitData {
293        public:
294                PatchMesh *patch;
295                int index;
296                int type;
297                PatchHitData(PatchMesh *patch, int index, int type)
298                        { this->patch = patch; this->index = index; this->type = type; }
299                ~PatchHitData() {}
300        };
301
302// Flags for sub object hit test
303
304// NOTE: these are the same bits used for object level.
305#define SUBHIT_PATCH_SELONLY    (1<<0)
306#define SUBHIT_PATCH_UNSELONLY  (1<<2)
307#define SUBHIT_PATCH_ABORTONHIT (1<<3)
308#define SUBHIT_PATCH_SELSOLID   (1<<4)
309
310#define SUBHIT_PATCH_VERTS              (1<<24)
311#define SUBHIT_PATCH_VECS               (1<<25)
312#define SUBHIT_PATCH_PATCHES    (1<<26)
313#define SUBHIT_PATCH_EDGES              (1<<27)
314#define SUBHIT_PATCH_TYPEMASK   (SUBHIT_PATCH_VERTS|SUBHIT_PATCH_VECS|SUBHIT_PATCH_EDGES|SUBHIT_PATCH_PATCHES)
315
316
317// Display flags
318#define DISP_VERTTICKS          (1<<0)
319
320#define DISP_SELVERTS           (1<<10)
321#define DISP_SELPATCHES         (1<<11)
322#define DISP_SELEDGES           (1<<12)
323#define DISP_SELPOLYS           (1<<13)
324
325#define DISP_LATTICE            (1<<16)
326#define DISP_VERTS                      (1<<17)
327
328// Selection level bits.
329#define PATCH_OBJECT            (1<<0)
330#define PATCH_VERTEX            (1<<1)
331#define PATCH_PATCH                     (1<<2)
332#define PATCH_EDGE                      (1<<3)
333
334// PatchMesh flags
335
336class PatchMesh {
337        friend class Patch;
338
339        private:
340#if MULTI_PROCESSING
341                static int              refCount;
342                static HANDLE   xfmThread;
343                static HANDLE   xfmMutex;
344                static HANDLE   xfmStartEvent;
345                static HANDLE   xfmEndEvent;
346                friend DWORD WINAPI xfmFunc(LPVOID ptr);
347#endif
348                // derived data-- can be regenerated
349                PRVertex                *rVerts;                // <<< instance specific.
350                GraphicsWindow  *cacheGW;               // identifies rVerts cache
351//              Point3                  *faceNormal;    // object space--depends on geom+topo
352                Box3                    bdgBox;                 // object space--depends on geom+topo
353 
354                // The number of interpolations this patch will use for mesh conversion
355                int                     meshSteps;
356                BOOL            adaptive;               
357
358                // Vertex and patch work arrays -- for snap code
359                int                     snapVCt;
360                int                     snapPCt;
361                char            *snapV;
362                char            *snapP;
363
364                // -------------------------------------
365                //
366                DWORD           flags;                  // work flags-
367
368//              float           norScale;           // scale of normals -- couldn't this be done
369                                                                        // automatically relative to bdgBox?
370                int             renderPatch( GraphicsWindow *gw, int index);
371                int             renderEdge( GraphicsWindow *gw, int index);
372//              void            calcNormal(int i);
373                void            checkRVertsAlloc(void);
374                void            setCacheGW(GraphicsWindow *gw)  { cacheGW = gw; }
375                GraphicsWindow *getCacheGW(void)                        { return cacheGW; }
376
377//              void            buildFaceNormals();
378//              void            checkNormals();
379
380                void            freeVerts();
381                void            freeTVerts();
382                void            freeVecs();
383                void            freePatches();
384                void            freeTVPatches();
385                void            freeEdges();
386                void            freeRVerts();
387                void            freePatchMtlIndexList(); 
388                void            freeSnapData();
389                int                     buildSnapData(GraphicsWindow *gw,int verts,int edges);
390
391        public:
392                // Topology
393                int                     numVerts;
394                int                     numVecs;
395                int                     numPatches;
396                int                     numEdges;
397                Patch *         patches;
398                PatchVec *      vecs;
399                PatchEdge *     edges;
400
401                // Geometry
402                PatchVert *     verts;
403
404                // Texture Coord assignment
405                int                     numTVerts;
406                UVVert *        tVerts;
407                TVPatch *       tvPatches;       
408
409                // Material assignment
410                DWORD           mtlIndex;     // object material
411                DWORD *         patchMtlIndex; // material per patch
412
413                // Selection
414                BitArray        vertSel;                // selected vertices
415                BitArray        edgeSel;                // selected edges
416                BitArray        patchSel;               // selected patches
417
418                // If hit bezier vector, this is its info:
419                int bezVecVert;
420
421                // Display attribute flags
422                DWORD           dispFlags;
423
424                // Selection level
425                DWORD           selLevel;
426
427
428                DllExport PatchMesh();
429                DllExport PatchMesh(PatchMesh& fromPatch);
430
431                DllExport void Init();
432
433                DllExport ~PatchMesh();
434
435                DllExport PatchMesh&            operator=(PatchMesh& fromPatchMesh);
436                DllExport PatchMesh&            operator=(Mesh& fromMesh);
437               
438                DllExport BOOL  setNumVerts(int ct, BOOL keep = FALSE);
439                int                             getNumVerts(void)       { return numVerts; }
440               
441                DllExport BOOL  setNumTVerts(int ct, BOOL keep=FALSE);
442                int                             getNumTVerts(void) const { return numTVerts; }
443
444                // These are parallel to patches
445                // These are called from setNumPatches() to maintain the same count.
446                //
447                // If they are NULL and keep = TRUE they stay NULL.
448                // If they are NULL and keep = FALSE they are allocated (3D verts also init themselves from the main vert array)
449                // If they are non-NULL and ct = 0 they are set to NULL (and freed)
450                DllExport BOOL  setNumTVPatches(int ct, BOOL keep=FALSE, int oldCt=0);
451               
452                DllExport BOOL  setNumVecs(int ct, BOOL keep = FALSE);
453                int                             getNumVecs(void)        { return numVecs; }
454               
455                DllExport BOOL  setNumPatches(int ct, BOOL keep = FALSE);
456                int                             getNumPatches(void)             { return numPatches; }
457
458                DllExport BOOL  setNumEdges(int ct, BOOL keep = FALSE);
459                int                             getNumEdges(void)               { return numEdges; }
460               
461                void            setVert(int i, const Point3 &xyz)       { verts[i].p = xyz; }
462                void            setVert(int i, float x, float y, float z)       { verts[i].p.x=x; verts[i].p.y=y; verts[i].p.z=z; }
463                void            setTVert(int i, const UVVert &xyz)      { tVerts[i] = xyz; }
464                void            setTVert(int i, float x, float y, float z)      { tVerts[i].x=x; tVerts[i].y=y; tVerts[i].z=z; }
465                void            setVec(int i, const Point3 &xyz)        { vecs[i].p = xyz; }
466                void            setVec(int i, float x, float y, float z)        { vecs[i].p.x=x; vecs[i].p.y=y; vecs[i].p.z=z; }
467               
468                PatchVert &     getVert(int i)          { return verts[i];  }
469                PatchVert *     getVertPtr(int i)       { return verts+i; }
470                UVVert &        getTVert(int i)         { return tVerts[i];  }
471                UVVert *        getTVertPtr(int i)      { return tVerts+i; }
472                PatchVec &      getVec(int i)           { return vecs[i];  }
473                PatchVec *      getVecPtr(int i)        { return vecs+i; }
474                PRVertex &      getRVert(int i)         { return rVerts[i]; }
475                PRVertex *      getRVertPtr(int i)      { return rVerts+i; }
476               
477                void            setMtlIndex(DWORD i)    { mtlIndex = i; }
478                DWORD           getMtlIndex(void)               { return mtlIndex; }
479                DWORD           getPatchMtlIndex(int i) { return patchMtlIndex? patchMtlIndex[i]: mtlIndex; }
480
481                // Automatically update all the adjacency info, etc.
482                // Returns TRUE if patch mesh is valid, FALSE if it's not!
483                DllExport BOOL          buildLinkages();
484               
485                // Compute the interior bezier points for each patch in the mesh
486                DllExport void          computeInteriors();
487//              DllExport void          buildNormals();
488
489                DllExport void          render(GraphicsWindow *gw, Material *ma, RECT *rp, int compFlags);
490                DllExport BOOL          select(GraphicsWindow *gw, Material *ma, HitRegion *hr, int abortOnHit = FALSE);
491                DllExport void          snap(GraphicsWindow *gw, SnapInfo *snap, IPoint2 *p, Matrix3 &tm);
492                DllExport BOOL          SubObjectHitTest(GraphicsWindow *gw, Material *ma, HitRegion *hr,
493                                                                DWORD flags, SubPatchHitList& hitList );
494
495                DllExport void          buildBoundingBox(void);
496                DllExport Box3          getBoundingBox(Matrix3 *tm=NULL); // RB: optional TM allows the box to be calculated in any space.
497                                                              // NOTE: this will be slower becuase all the points must be transformed.
498               
499                DllExport void          InvalidateGeomCache();
500                DllExport void          FreeAll(); //DS
501                               
502                // functions for use in data flow evaluation
503                DllExport void          ShallowCopy(PatchMesh *amesh, unsigned long channels);
504                DllExport void          DeepCopy(PatchMesh *amesh, unsigned long channels);
505                DllExport void          NewAndCopyChannels(unsigned long channels);
506                DllExport void          FreeChannels( unsigned long channels, int zeroOthers=1);
507
508                // Display flags
509                void            SetDispFlag(DWORD f) { dispFlags |= f; }
510                DWORD           GetDispFlag(DWORD f) { return dispFlags & f; }
511                void            ClearDispFlag(DWORD f) { dispFlags &= ~f; }
512
513                // Selection access
514                BitArray&       VertSel() { return vertSel;  } 
515                BitArray&       PatchSel() { return patchSel;  }       
516                BitArray&       EdgeSel() { return edgeSel;  } 
517
518                // Constructs a vertex selection list based on the current selection level.
519                DllExport BitArray      VertexTempSel();
520
521                // Apply the coplanar constraints to the patch mesh
522                // (Optionally only apply it to selected vertices)
523                DllExport void ApplyConstraints(BOOL selOnly = FALSE);
524
525                // Create triangular or quadrilateral patch
526                DllExport BOOL MakeQuadPatch(int index, int va, int vab, int vba, int vb, int vbc, int vcb, int vc, int vcd, int vdc, int vd, int vda, int vad, int i1, int i2, int i3, int i4, DWORD sm);
527                DllExport BOOL MakeTriPatch(int index, int va, int vab, int vba, int vb, int vbc, int vcb, int vc, int vca, int vac, int i1, int i2, int i3, DWORD sm);
528
529                // Get/Set mesh steps, adaptive switch
530                DllExport void SetMeshSteps(int steps);
531                DllExport int GetMeshSteps();
532                DllExport void SetAdaptive(BOOL sw);
533                DllExport BOOL GetAdaptive();
534
535                // Find the edge index for a given vertex-vector-vector-vertex sequence
536                int GetEdge(int v1, int v12, int v21, int v2, int p);
537
538                // Apply mapping to the patch mesh
539                DllExport void ApplyUVWMap(int type,
540                        float utile, float vtile, float wtile,
541                        int uflip, int vflip, int wflip, int cap,
542                        const Matrix3 &tm);
543
544                // Dump the patch mesh structure via DebugPrints
545                DllExport void Dump();
546
547                DllExport IOResult Save(ISave* isave);
548                DllExport IOResult Load(ILoad* iload);
549
550        };
551
552
553#endif // _PATCH_H_
Note: See TracBrowser for help on using the repository browser.