Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Tools/LightwaveConverter/src/lwLayer.cpp @ 7

Last change on this file since 7 was 6, checked in by anonymous, 17 years ago

=…

File size: 7.6 KB
Line 
1#include "lwLayer.h"
2
3/*======================================================================
4lwResolveVertexPoints()
5
6  For each point, fill in the indexes of the polygons that share the
7  point.  Returns 0 if any of the memory allocations fail, otherwise
8  returns 1.
9====================================================================== */
10
11void lwLayer::lwResolveVertexPoints(void)
12{
13        unsigned int i, j;
14       
15        for ( i = 0; i < polygons.size(); i++ )
16        {
17                lwPolygon *polygon = polygons[ i ];
18                for ( j = 0; j < polygon->vertices.size(); j++ )
19                {
20                        lwVertex *vertex = polygon->vertices[ j ];
21                        vertex->point = points[ vertex->index ];
22                }
23        }       
24}
25
26/*======================================================================
27lwGetPointPolygons()
28
29For each point, fill in the indexes of the polygons that share the point.
30====================================================================== */
31
32void lwLayer::lwGetPointPolygons(void)
33{
34        unsigned int i, j;
35       
36        for ( i = 0; i < polygons.size(); i++ )
37        {
38                lwPolygon *polygon = polygons[ i ];
39                for ( j = 0; j < polygon->vertices.size(); j++ )
40                        polygon->vertices[ j ]->point->polygons.push_back(polygon);
41        }       
42}
43
44/*
45======================================================================
46calculatePolygonNormals()
47
48  Calculate the polygon normals.  By convention, LW's polygon normals
49  are found as the cross product of the first and last edges.  It's
50  undefined for one- and two-point polygons.
51====================================================================== */
52
53void lwLayer::calculatePolygonNormals(void)
54{
55        for (unsigned int i = 0; i < polygons.size(); polygons[i++]->calculateNormal());
56}
57
58void lwLayer::triangulatePolygons(void)
59{
60        vpolygons newpolygons;
61        vpolygons newtriangles;
62
63        unsigned int i, j;
64
65        for (i = 0; i < polygons.size(); i++)
66        {
67                lwPolygon *polygon = polygons[i];
68               
69                if (polygon->vertices.size() > 3) // needs triangulation !
70                {
71                        newtriangles = polygon->triangulate();
72                        delete polygon;
73
74                        for (j = 0; j < newtriangles.size(); j++)
75                        {
76                                polygon = newtriangles[j];
77                                polygon->calculateNormal();
78                                newpolygons.push_back(polygon);
79                        }
80                }
81                else
82                        newpolygons.push_back(polygon);
83        }
84
85        polygons = newpolygons;
86}
87
88/*
89======================================================================
90lwGetBoundingBox()
91
92  Calculate the bounding box for a point list, but only if the bounding
93  box hasn't already been initialized.
94====================================================================== */
95
96void lwLayer::lwGetBoundingBox(void)
97{
98        unsigned int i;
99       
100        if ( points.size() == 0 ) return;
101       
102        if ( bboxmin.x != 0.0f ) return;
103        if ( bboxmin.y != 0.0f ) return;
104        if ( bboxmin.z != 0.0f ) return;
105        if ( bboxmax.x != 0.0f ) return;
106        if ( bboxmax.y != 0.0f ) return;
107        if ( bboxmax.z != 0.0f ) return;
108       
109        bboxmin.x = bboxmin.y = bboxmin.z = 1e20f;
110        bboxmax.x = bboxmax.y = bboxmax.z = -1e20f;
111       
112        for ( i = 0; i < points.size(); i++ )
113        {
114                if ( bboxmin.x > points[ i ]->x )
115                        bboxmin.x = points[ i ]->x;
116                if ( bboxmin.y > points[ i ]->y )
117                        bboxmin.y = points[ i ]->y;
118                if ( bboxmin.z > points[ i ]->z )
119                        bboxmin.z = points[ i ]->z;
120               
121                if ( bboxmax.x < points[ i ]->x )
122                        bboxmax.x = points[ i ]->x;
123                if ( bboxmax.y < points[ i ]->y )
124                        bboxmax.y = points[ i ]->y;
125                if ( bboxmax.z < points[ i ]->z )
126                        bboxmax.z = points[ i ]->z;
127        }
128}
129
130/*
131======================================================================
132lwResolvePolySurfaces()
133
134  Convert tag indexes into actual lwSurface pointers.  If any polygons
135  point to tags for which no corresponding surface can be found, a
136  default surface is created.
137====================================================================== */
138
139int lwLayer::lwResolvePolySurfaces( vsurfaces &surfaces, vtags &tags )
140{
141        if ( tags.size() == 0 ) return 1;
142       
143        lwSurface **s = (lwSurface **)malloc (tags.size() * sizeof(lwSurface *));
144       
145        if ( !s ) return 0;
146       
147        unsigned int i, j, index;
148       
149        for ( i = 0; i < tags.size(); i++ )
150        {
151                s[i] = 0;
152                for (j = 0; j < surfaces.size(); j++)
153                {
154                        if ( !strcmp( surfaces[j]->name, tags[i] ))
155                        {
156                                s[i] = surfaces[j];
157                                break;
158                        }
159                }
160                if ( !s[i])
161                {
162                        s[i] = lwSurface::lwDefaultSurface();
163                        if ( !s[i] ) return 0;
164
165                        s[i]->name = (char *)malloc(strlen(tags[i])+1);                 
166                        if ( !s[i]->name ) return 0;
167
168                        strcpy( s[i]->name, tags[i] );
169                }
170        }
171
172        surfaces.clear();
173        surfaces.reserve(tags.size());
174        for (i = 0; i < tags.size(); i++ )
175                surfaces.push_back(s[i]);
176
177        for (i = 0; i < polygons.size(); i++ )
178        {
179                index = polygons[i]->surfidx;
180                if ( index < 0 || index > tags.size() ) return 0;
181                polygons[i]->surface = s[index];
182        }
183
184        free(s);
185        return 1;
186}
187
188
189/*
190======================================================================
191calculateVertexNormals()
192
193  Calculate the vertex normals.  For each polygon vertex, sum the
194  normals of the polygons that share the point.  If the normals of the
195  current and adjacent polygons form an angle greater than the max
196  smoothing angle for the current polygon's surface, the normal of the
197  adjacent polygon is excluded from the sum.  It's also excluded if the
198  polygons aren't in the same smoothing group.
199 
200        Assumes that lwGetPointPolygons(), lwGetPolyNormals() and
201        lwResolvePolySurfaces() have already been called.
202====================================================================== */
203
204void lwLayer::calculateVertexNormals(void)
205{
206        unsigned int j, n, g;
207        float a;
208        lwPolygon *outerpolygon;
209        lwPolygon *innerpolygon;
210        lwVertex *vertex;
211        lwPoint *point;
212       
213        for ( j = 0; j < polygons.size(); j++ )
214        {
215                outerpolygon = polygons[j];
216                for ( n = 0; n < outerpolygon->vertices.size(); n++ )
217                {
218                        vertex = outerpolygon->vertices[n];
219                        vertex->normal = outerpolygon->normal;
220                       
221                        if ( outerpolygon->surface->smooth <= 0 ) continue;
222                       
223                        point = points[vertex->index];
224                       
225                        for ( g = 0; g < point->polygons.size(); g++ )
226                        {
227                                innerpolygon = point->polygons[ g ];
228                                if ( innerpolygon == outerpolygon ) continue;
229                                if ( outerpolygon->smoothgrp != innerpolygon->smoothgrp ) continue;
230                                a = (float)acos( outerpolygon->normal.dotProduct(innerpolygon->normal) );
231                                if ( a > outerpolygon->surface->smooth ) continue;
232                                vertex->normal += innerpolygon->normal;
233                        }
234                       
235                        vertex->normal.normalise();
236                }
237        }
238}
239
240/*
241======================================================================
242lwGetPointVMaps()
243
244  Fill in the lwVMapPt structure for each point.
245====================================================================== */
246
247void lwLayer::lwGetPointVMaps(void)
248{
249        lwVMap *vm;
250        unsigned int i, j;
251       
252        for (j = 0; j < vmaps.size(); j++)
253        {
254                vm = vmaps[j];
255                if ( !vm->perpoly )
256                {
257                        for ( i = 0; i < vm->nverts; i++ )
258                        {
259                                points[ vm->vindex[ i ] ]->vmaps.push_back( lwVMapPt(vm, i) );
260                        }
261                }
262        }
263}
264
265
266/*
267======================================================================
268lwGetPolyVMaps()
269
270  Fill in the lwVMapPt structure for each polygon vertex.
271====================================================================== */
272
273void lwLayer::lwGetPolyVMaps(void)
274{
275        lwVMap *vm;
276        lwVertex *pv;
277        unsigned int i, j, k;
278       
279        /* fill in vmap references for each mapped point */
280        for (k = 0; k < vmaps.size(); k++)
281        {
282                vm = vmaps[k];
283                if ( vm->perpoly )
284                {
285                        for ( i = 0; i < vm->nverts; i++ )
286                        {
287                                for ( j = 0; j < polygons[ vm->pindex[ i ]]->vertices.size(); j++ )
288                                {
289                                        pv = polygons[ vm->pindex[ i ]]->vertices[ j ];
290                                        if ( vm->vindex[ i ] == pv->index )
291                                        {
292                                                pv->vmaps.push_back( lwVMapPt(vm, i) );
293                                                break;
294                                        }
295                                }
296                        }
297                }
298        }
299}
Note: See TracBrowser for help on using the repository browser.