root/OpenSceneGraph/trunk/src/osgPlugins/lwo/Unit.cpp @ 13041

Revision 13041, 8.3 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*******************************************************
2      Lightwave Object Loader for OSG
3
4  Copyright (C) 2004 Marco Jez <marco.jez@poste.it>
5  OpenSceneGraph is (C) 2004 Robert Osfield
6********************************************************/
7
8#include "Unit.h"
9
10using namespace lwosg;
11
12Unit::Unit()
13:    points_(new osg::Vec3Array),
14    normals_(new VertexMap),
15    weight_maps_(new VertexMap_map),
16    subpatch_weight_maps_(new VertexMap_map),
17    texture_maps_(new VertexMap_map),
18    rgb_maps_(new VertexMap_map),
19    rgba_maps_(new VertexMap_map),
20    displacement_maps_(new VertexMap_map),
21    spot_maps_(new VertexMap_map)
22{
23}
24
25float Unit::angle_between_polygons(const Polygon &p1, const Polygon &p2) const
26{
27    float a = p1.face_normal(points_.get()) * p2.face_normal(points_.get());
28    if (a > 1) return 0;
29    if (a < -1) return osg::PI;
30    return acosf(a);
31}
32
33void Unit::find_shared_polygons(int vertex_index, std::vector<int> &poly_indices)
34{
35    int k = 0;
36    for (Polygon_list::const_iterator i=polygons_.begin(); i!=polygons_.end(); ++i, ++k) {
37        for (Polygon::Index_list::const_iterator j=i->indices().begin(); j!=i->indices().end(); ++j) {
38            if (*j == vertex_index) {
39                poly_indices.push_back(k);
40                break;
41            }
42        }
43    }
44}
45
46void Unit::generate_normals()
47{
48    // create smoothed normals
49    for (Polygon_list::iterator i=polygons_.begin(); i!=polygons_.end(); ++i) {
50        osg::Vec4 N = osg::Vec4(i->face_normal(points_.get()), 0);
51        for (Polygon::Index_list::iterator j=i->indices().begin(); j!=i->indices().end(); ++j) {
52            (*normals_.get())[*j] += N;
53        }
54    }
55
56    // normalize smoothed normals
57    for (VertexMap::iterator ni=normals_->begin(); ni!=normals_->end(); ++ni) {
58        float l = ni->second.length();
59        if (l != 0) ni->second /= l;
60    }
61
62    // compute per-polygon normals
63    int pn = 0;
64    for (Polygon_list::iterator pi=polygons_.begin(); pi!=polygons_.end(); ++pi, ++pn) {
65
66        Polygon &poly = *pi;
67
68        float max_smoothing_angle = 0;
69        if (poly.has_surface()) {
70            max_smoothing_angle = poly.get_surface()->get_max_smoothing_angle();
71        }
72
73        for (Polygon::Index_list::const_iterator j=poly.indices().begin(); j!=poly.indices().end(); ++j) {
74
75            osg::Vec4 N(poly.face_normal(points_.get()), 0);
76            unsigned num_smoothed = 1;
77
78            const Index_list &shared_polys = shares_.at(*j);
79
80            for (unsigned k=0; k<shared_polys.size(); ++k) {
81                if (shared_polys[k] != pn) {
82                    const Polygon &shared_poly = polygons_.at(shared_polys[k]);
83                    float angle = angle_between_polygons(poly, shared_poly);
84                    if (angle <= max_smoothing_angle && (poly.get_smoothing_group() == shared_poly.get_smoothing_group())) {
85                        N += osg::Vec4(shared_poly.face_normal(points_.get()), 0);
86                        ++num_smoothed;
87                    }
88                }
89            }
90
91            if (num_smoothed != shared_polys.size()) {
92                float l = N.length();
93                if (l != 0) N /= l;
94                (*poly.local_normals())[*j] = N;
95            }
96        }
97    }
98}
99
100void Unit::flatten_maps()
101{
102    for (Polygon_list::iterator i=polygons().begin(); i!=polygons().end(); ++i) {
103
104        // flatten normal map
105        flatten_map(*i, i->local_normals(), normals_.get());
106        i->local_normals()->clear();
107
108        VertexMap_map::const_iterator j;
109
110        // flatten weight maps
111        while (!i->weight_maps()->empty()) {
112            VertexMap_map::iterator j = i->weight_maps()->begin();
113            flatten_map(*i, j->second.get(), weight_maps_->getOrCreate(j->first));
114            i->weight_maps()->erase(j);
115        }
116
117        // flatten texture maps
118        while (!i->texture_maps()->empty()) {
119            VertexMap_map::iterator j = i->texture_maps()->begin();
120            flatten_map(*i, j->second.get(), texture_maps_->getOrCreate(j->first));
121            i->texture_maps()->erase(j);
122        }
123
124        // flatten rgb maps
125        while (!i->rgb_maps()->empty()) {
126            VertexMap_map::iterator j = i->rgb_maps()->begin();
127            flatten_map(*i, j->second.get(), rgb_maps_->getOrCreate(j->first));
128            i->rgb_maps()->erase(j);
129        }
130
131        // flatten rgba maps
132        while (!i->rgba_maps()->empty()) {
133            VertexMap_map::iterator j = i->rgba_maps()->begin();
134            flatten_map(*i, j->second.get(), rgba_maps_->getOrCreate(j->first));
135            i->rgba_maps()->erase(j);
136        }
137
138    }
139}
140
141void Unit::flatten_map(Polygon &poly, const VertexMap *local_map, VertexMap *global_map)
142{
143    int j = 0;
144    for (Polygon::Index_list::iterator i=poly.indices().begin(); i!=poly.indices().end(); ++i, ++j) {
145
146        // try original vertex index
147        VertexMap::const_iterator k = local_map->find(*i);
148
149        // try duplicated vertex index
150        if (k == local_map->end()) {
151            k = local_map->find(poly.dup_vertices()[j]);
152        }
153
154        if (k != local_map->end()) {
155
156            // duplication may be needed!
157            if (poly.dup_vertices()[j] == 0) {
158
159                // duplicate point
160                points_->push_back(points_->at(*i));
161
162                int new_index = static_cast<int>(points_->size())-1;
163
164                // duplicate normal
165                (*normals_.get())[new_index] = (*normals_.get())[*i];
166
167                // duplicate share
168                shares_.push_back(shares_.at(*i));
169
170                VertexMap_map::iterator vm;
171
172                // duplicate weights
173                for (vm=weight_maps()->begin(); vm!=weight_maps()->end(); ++vm) {
174                    if (vm->second->find(*i) != vm->second->end())
175                        (*vm->second.get())[new_index] = (*vm->second.get())[*i];
176                }
177
178                // duplicate subpatch weights
179                for (vm=subpatch_weight_maps()->begin(); vm!=subpatch_weight_maps()->end(); ++vm) {
180                    if (vm->second->find(*i) != vm->second->end())
181                        (*vm->second.get())[new_index] = (*vm->second.get())[*i];
182                }
183
184                // duplicate texture UVs
185                for (vm=texture_maps()->begin(); vm!=texture_maps()->end(); ++vm) {
186                    if (vm->second->find(*i) != vm->second->end())
187                        (*vm->second.get())[new_index] = (*vm->second.get())[*i];
188                }
189
190                // duplicate RGBs
191                for (vm=rgb_maps()->begin(); vm!=rgb_maps()->end(); ++vm) {
192                    if (vm->second->find(*i) != vm->second->end())
193                        (*vm->second.get())[new_index] = (*vm->second.get())[*i];
194                }
195
196                // duplicate RGBAs
197                for (vm=rgba_maps()->begin(); vm!=rgba_maps()->end(); ++vm) {
198                    if (vm->second->find(*i) != vm->second->end())
199                        (*vm->second.get())[new_index] = (*vm->second.get())[*i];
200                }
201
202                // duplicate displacements
203                for (vm=displacement_maps()->begin(); vm!=displacement_maps()->end(); ++vm) {
204                    if (vm->second->find(*i) != vm->second->end())
205                        (*vm->second.get())[new_index] = (*vm->second.get())[*i];
206                }
207
208                // duplicate spots
209                for (vm=spot_maps()->begin(); vm!=spot_maps()->end(); ++vm) {
210                    if (vm->second->find(*i) != vm->second->end())
211                        (*vm->second.get())[new_index] = (*vm->second.get())[*i];
212                }
213
214                // update vertex index
215                poly.dup_vertices()[j] = *i;
216                *i = new_index;
217            }
218
219            (*global_map)[*i] = k->second;
220        }
221    }
222}
223
224void Unit::compute_vertex_remapping(const Surface *surf, Index_list &remap) const
225{
226    remap.assign(points_->size(), -1);
227    for (Polygon_list::const_iterator i=polygons_.begin(); i!=polygons_.end(); ++i) {
228        if (i->get_surface() == surf) {
229            for (Polygon::Index_list::const_iterator j=i->indices().begin(); j!=i->indices().end(); ++j) {
230                remap[*j] = *j;
231            }
232        }
233    }
234    int offset = 0;
235    for (Index_list::iterator j=remap.begin(); j!=remap.end(); ++j) {
236        if (*j == -1) {
237            ++offset;
238        } else {
239            *j -= offset;
240        }
241    }
242}
Note: See TracBrowser for help on using the browser.