1 /* Copyright (C) 2006-2007 Claus-Justus Heine
2 *
3 * This file is part of Geomview.
4 *
5 * Geomview is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * Geomview is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with Geomview; see the file COPYING. If not, write
17 * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
18 * USA, or visit http://www.gnu.org.
19 */
20 #ifndef _GV_BSPTREE_P_H_
21 #define _GV_BSPTREE_P_H_
22
23 #include "geomclass.h"
24 #include "nodedata.h"
25 #include "bsptree.h"
26
27 #include "obstack.h"
28
29 struct Poly;
30
31 typedef struct PolyListNode PolyListNode;
32 struct PolyListNode
33 {
34 PolyListNode *next;
35 struct Poly *poly;
36 Point3 *pn; /* If we split a polygon we compute the normal on
37 * the parent to avoid numerical instabilities
38 * caused by increasingly degenerated polygons.
39 */
40
41 const void **tagged_app; /* pointer to shared storage for the
42 * return value of mgtagappearance().
43 */
44 };
45
46 typedef struct BSPTreeNode BSPTreeNode;
47 struct BSPTreeNode
48 {
49 BSPTreeNode *front;
50 BSPTreeNode *back;
51 HPoint3 plane;
52 PolyListNode *polylist;
53 };
54
55 struct BSPTree {
56 BSPTreeNode *tree; /* The root of the BSPtree itself */
57 Geom *geom; /* The top-level Geom we belong to */
58 bool oneshot; /* Tree is destroyed after drawing; useful
59 * for location/oring != LOCAL INSTs and
60 * during ND-drawing. The oneshot flag is
61 * reset after it took affect.
62 */
63 PolyListNode *init_lpl; /* While tree == NULL elements can be
64 * added to this list
65 */
66 TransformPtr Tid; /* INST support: to support absolute
67 * positioning (location and origin !=
68 * LOCAL) we need the position of the
69 * top-level geometry (the one who owns the
70 * tree, i.e. tree->geom).
71 */
72 TransformPtr Tidinv; /* Inverse of Tid, only computed on demand */
73 TransformPtr T; /* INST support: transform polygons during
74 * tree generation, i.e. before adding
75 * them to init_lpl.
76 */
77 Transform Tdual; /* We need the dual of T to transform the normals
78 * correctly ( y^t x = 0 <=> y^t T T^{-tr}x = 0).
79 */
80 TransformPtr TxT; /* texture transform */
81 const void **tagged_app;
82
83 struct obstack obst; /* Scratch space for new polygons etc */
84 };
85
86 /* if we have an appearance (but no handle to an appearance ) which
87 * overrides the transparency flag to false _or_ a material which
88 * overrides the alpha value to 1.0 (and no own color spec with alpha
89 * != 1.0) then we need not add ourselves to the BSP-tree: no facet of
90 * this Geom will ever be translucent.
91 *
92 * This does, of course, not work with INSTs or LISTs, but only with
93 * "atomic" Geom's
94 */
never_translucent(Geom * geom)95 static inline bool never_translucent(Geom *geom)
96 {
97 Appearance *ap = geom->ap;
98
99 return (ap && !geom->aphandle &&
100 (((ap->override & APF_FACEDRAW) && (ap->flag & APF_FACEDRAW) == 0)
101 ||
102 ((ap->override & APF_TRANSP) && (ap->flag & APF_TRANSP) == 0)
103 ||
104 ((geom->geomflags & COLOR_ALPHA) == 0 && ap->mat &&
105 (ap->mat->override & MTF_ALPHA) && ap->mat->diffuse.a == 1.0)));
106 }
107
108 /* Load the current transform form the MG-layer into tree->Tid */
BSPTreeSetId(BSPTree * tree)109 static inline void BSPTreeSetId(BSPTree *tree)
110 {
111 Transform T;
112
113 if (tree->geom == NULL || tree != tree->geom->bsptree) {
114 abort();
115 }
116
117 /* make sure the top-level geom has per-node data */
118 GeomNodeDataCreate(tree->geom, NULL);
119
120 mggettransform(T);
121 if (memcmp(T, TM_IDENTITY, sizeof(Transform)) != 0) {
122 tree->Tid = obstack_alloc(&tree->obst, sizeof(Transform));
123 TmCopy(T, tree->Tid);
124 } else {
125 tree->Tid = TM_IDENTITY;
126 }
127 tree->Tidinv = NULL;
128 }
129
BSPTreePushAppearance(BSPTree * bsptree,Geom * geom)130 static inline const void **BSPTreePushAppearance(BSPTree *bsptree, Geom *geom)
131 {
132 NodeData *data = GeomNodeDataCreate(geom, NULL);
133 const void **tagged_app = bsptree->tagged_app;
134
135 bsptree->tagged_app = &data->tagged_ap;
136 return tagged_app;
137 }
138
139 static inline void
BSPTreePopAppearance(BSPTree * bsptree,const void ** old_tagged_app)140 BSPTreePopAppearance(BSPTree *bsptree, const void **old_tagged_app)
141 {
142 if (bsptree != NULL && old_tagged_app != NULL) {
143 bsptree->tagged_app = old_tagged_app;
144 }
145 }
146
BSPTreePushTransform(BSPTree * tree,TransformPtr T)147 static inline TransformPtr BSPTreePushTransform(BSPTree *tree, TransformPtr T)
148 {
149 TransformPtr old_T;
150
151 if (tree != NULL) {
152 old_T = tree->T;
153 tree->T = T;
154 if (T != TM_IDENTITY) {
155 TmDual(T, tree->Tdual);
156 }
157 return old_T;
158 } else {
159 return TM_IDENTITY;
160 }
161 }
162
BSPTreeSetTransform(BSPTree * tree,TransformPtr T)163 static inline void BSPTreeSetTransform(BSPTree *tree, TransformPtr T)
164 {
165 if (tree != NULL) {
166 tree->T = T;
167 if (T != TM_IDENTITY) {
168 TmDual(T, tree->Tdual);
169 }
170 }
171 }
172
BSPTreePopTransform(BSPTree * tree,TransformPtr old_T)173 static inline void BSPTreePopTransform(BSPTree *tree, TransformPtr old_T)
174 {
175 if (tree != NULL) {
176 tree->T = old_T;
177 if (old_T != TM_IDENTITY) {
178 TmDual(old_T, tree->Tdual);
179 }
180 }
181 }
182
BSPTreePushTxTransform(BSPTree * tree,TransformPtr T)183 static inline TransformPtr BSPTreePushTxTransform(BSPTree *tree, TransformPtr T)
184 {
185 TransformPtr old_TxT;
186
187 if (tree != NULL) {
188 old_TxT = tree->TxT;
189 tree->TxT = T;
190 return old_TxT;
191 } else {
192 return TM_IDENTITY;
193 }
194 }
195
BSPTreeSetTxTransform(BSPTree * tree,TransformPtr T)196 static inline void BSPTreeSetTxTransform(BSPTree *tree, TransformPtr T)
197 {
198 if (tree != NULL) {
199 tree->TxT = T;
200 }
201 }
202
BSPTreePopTxTransform(BSPTree * tree,TransformPtr old_T)203 static inline void BSPTreePopTxTransform(BSPTree *tree, TransformPtr old_T)
204 {
205 if (tree != NULL) {
206 tree->TxT = old_T;
207 }
208 }
209
210 #endif
211
212 /*
213 * Local Variables: ***
214 * c-basic-offset: 2 ***
215 * End: ***
216 */
217