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

Revision 13041, 14.5 kB (checked in by robert, 2 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 version 2 loader for Open Scene Graph
3 * Version 2 introduced in Lightwave v6.0
4 *
5 * Copyright (C) 2002 Pavel Moloshtan <pasha@moloshtan.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20 *
21 * The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
22 * real-time rendering of large 3D photo-realistic models.
23 * The OSG homepage is http://www.openscenegraph.org/
24 */
25
26#include "old_Lwo2Layer.h"
27#include <osg/io_utils>
28
29Lwo2Layer::Lwo2Layer():
30  _number(0),
31  _flags(0),
32  _parent(0)
33{
34}
35
36Lwo2Layer::~Lwo2Layer()
37{
38}
39
40
41void
42Lwo2Layer::notify(NotifySeverity severity)
43{
44  OSG_NOTIFY(severity) << "Current layer: " << _number << endl;
45  OSG_NOTIFY(severity) << "  flags  \t" << _flags << endl;
46  OSG_NOTIFY(severity) << "  pivot  \t" << _pivot << endl;
47  OSG_NOTIFY(severity) << "  name:  \t'" << _name.c_str() << "'" << endl;
48  OSG_NOTIFY(severity) << "  parent:\t" << _parent << endl;
49
50  // points
51  OSG_NOTIFY(severity) << "  points:\t" << _points.size() << endl;
52  OSG_NOTIFY(severity) << "\tcoord\t\t\t\ttexcoord" <<  endl;
53  OSG_NOTIFY(severity) << "\t=====\t\t\t\t========" <<  endl;
54  IteratorPoint itr;
55  for (itr = _points.begin(); itr != _points.end(); itr++)
56    {
57      OSG_NOTIFY(severity) << "    \t" << (*itr).coord << "\t\t" << (*itr).texcoord << endl;
58    }
59
60  // polygons
61  OSG_NOTIFY(severity) << "  polygons:\t" << _polygons.size() << endl;
62  OSG_NOTIFY(severity) << "\tcoord\t\t\t\ttexcoord" <<  endl;
63  OSG_NOTIFY(severity) << "\t=====\t\t\t\t========" <<  endl;
64  IteratorPolygonsList polygon_iterator;
65  int polygon_index = 0;
66  for (polygon_iterator = _polygons.begin(); polygon_iterator != _polygons.end(); polygon_iterator++, polygon_index++)
67    {
68      OSG_NOTIFY(severity) << "    \t" << polygon_index << " ("<< (*polygon_iterator).size() << " vertexes" << "):" << endl;
69      for (itr = (*polygon_iterator).begin(); itr != (*polygon_iterator).end(); itr++)
70        {
71          OSG_NOTIFY(severity) << "    \t" << (*itr).coord << "\t\t" << (*itr).texcoord << endl;
72        }
73      OSG_NOTIFY(severity) << endl;
74    }
75
76  // polygons tags
77  OSG_NOTIFY(severity) << "  polygons tags:\t" << _polygons_tag.size() << endl;
78  IteratorShort short_itr;
79  for (short_itr = _polygons_tag.begin(); short_itr != _polygons_tag.end(); short_itr++)
80    {
81      OSG_NOTIFY(severity) << "\t" << (*short_itr) << endl;
82    }
83}
84
85void
86Lwo2Layer::GenerateGeode( Geode& geode, short tags_count, DrawableToTagMapping& tag_mapping)
87{
88  OSG_DEBUG;
89
90  // variable used to track using textures
91  bool have_texture_coords;
92
93  // create diffirent geomerty for each tag
94  for (short current_tag = 0; current_tag < tags_count; current_tag++)
95    {
96      have_texture_coords = false;
97
98      // new geometry
99      ref_ptr<Geometry> geometry = new Geometry;
100
101      // create coords array
102      ref_ptr<Vec3Array> coords = new Vec3Array;
103
104      // create texture array
105      ref_ptr<Vec2Array> texcoords = new Vec2Array;
106
107      // selecting polygons for current layer only
108      int polygon_index = 0;
109      PolygonsList polygons;
110      IteratorPolygonsList polygon_iterator;
111      for (polygon_iterator = _polygons.begin(); polygon_iterator != _polygons.end(); polygon_iterator++, polygon_index++)
112        {
113          // *polygon_iterator it's a PolygonsList
114
115          // polygons of current tag only
116          if (_polygons_tag[polygon_index] == current_tag)
117            {
118
119              // reset point_index member for later comparing poins data
120              PointsList points_list = *polygon_iterator;
121              for (unsigned int i = 0; i < points_list.size(); i++)
122                {
123                  points_list[i].point_index = 0;
124                }
125
126              polygons.push_back(*polygon_iterator);
127            }
128        }
129
130      // find and compose triangle fans
131      PolygonsList triangle_fans;
132      _find_triangle_fans(polygons, triangle_fans);
133
134      // find and compose triangle strips
135      PolygonsList triangle_strips;
136      _find_triangle_strips(polygons, triangle_strips);
137
138      // polygons of current layer
139      polygon_index = 0;
140      for (polygon_iterator = polygons.begin(); polygon_iterator != polygons.end(); polygon_iterator++, polygon_index++)
141        {
142          if ((*polygon_iterator)[0].point_index != -1)
143            {
144              // all points of polygon
145              for (IteratorPoint itr = (*polygon_iterator).begin(); itr != (*polygon_iterator).end(); itr++)
146                {
147                  // *itr - it's a PointData
148
149                  // polygons data
150                  (*coords).push_back((*itr).coord);
151                  (*texcoords).push_back((*itr).texcoord);
152
153                  if ((*itr).texcoord.x() != -1.0f || (*itr).texcoord.y() != -1.0f)
154                    {
155                      have_texture_coords = true;
156                    }
157                }
158
159              unsigned int points_start = (*coords).size() - (*polygon_iterator).size();
160              unsigned int points_count = (*polygon_iterator).size();
161              if (points_count == 3)
162                {
163                  geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::TRIANGLES, points_start, points_count));
164                }
165              else if (points_count == 4)
166                {
167                  geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS, points_start, points_count));
168                }
169              else
170                {
171                  geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::POLYGON, points_start, points_count));
172                }
173            }
174        }
175
176      // triangle fans of current layer
177      polygon_index = 0;
178      for (polygon_iterator = triangle_fans.begin(); polygon_iterator != triangle_fans.end(); polygon_iterator++, polygon_index++)
179        {
180
181          // all points of polygon
182          for (IteratorPoint itr = (*polygon_iterator).begin(); itr != (*polygon_iterator).end(); itr++)
183            {
184              // *itr - it's a PointData
185
186              // polygons data
187              (*coords).push_back((*itr).coord);
188              (*texcoords).push_back((*itr).texcoord);
189
190              if ((*itr).texcoord.x() != -1.0f || (*itr).texcoord.y() != -1.0f)
191                {
192                  have_texture_coords = true;
193                }
194            }
195
196          unsigned int points_start = (*coords).size() - (*polygon_iterator).size();
197          unsigned int points_count = (*polygon_iterator).size();
198          geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::TRIANGLE_FAN, points_start, points_count));
199        }
200
201      // triangle strips of current layer
202      polygon_index = 0;
203      for (polygon_iterator = triangle_strips.begin(); polygon_iterator != triangle_strips.end(); polygon_iterator++, polygon_index++)
204        {
205
206          // all points of polygon
207          for (IteratorPoint itr = (*polygon_iterator).begin(); itr != (*polygon_iterator).end(); itr++)
208            {
209              // *itr - it's a PointData
210
211              // polygons data
212              (*coords).push_back((*itr).coord);
213              (*texcoords).push_back((*itr).texcoord);
214
215              if ((*itr).texcoord.x() != -1.0f || (*itr).texcoord.y() != -1.0f)
216                {
217                  have_texture_coords = true;
218                }
219            }
220
221          unsigned int points_start = (*coords).size() - (*polygon_iterator).size();
222          unsigned int points_count = (*polygon_iterator).size();
223          geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::TRIANGLE_STRIP, points_start, points_count));
224        }
225
226      // add geometry if it contains any points
227      if (coords->size() != 0)
228        {
229          geometry->setVertexArray(coords.get());
230
231          // assign texture array
232          if (have_texture_coords)
233            {
234              geometry->setTexCoordArray(0, texcoords.get());
235            }
236
237          // generate normals
238          osgUtil::SmoothingVisitor smoother;
239          smoother.smooth(*(geometry.get()));
240
241          geode.addDrawable(geometry.get());
242
243          OSG_DEBUG << "  inserting tag " << geode.getNumDrawables() - 1 << ":" << current_tag << std::endl;
244          tag_mapping.insert(PairDrawableToTag(geode.getNumDrawables() - 1, current_tag));
245        }
246    }
247}
248
249bool
250Lwo2Layer::_find_triangle_fans(PolygonsList& polygons, PolygonsList& triangle_fans)
251{
252  bool found = false;
253
254  while (_find_triangle_fan(polygons, triangle_fans))
255    {
256      found = true;
257    }
258
259  if (triangle_fans.size() > 0)
260    {
261      OSG_INFO << "LWO2 loader, optimizing: found " << triangle_fans.size() << " triangle fans" << endl;
262    }
263
264  return found;
265}
266
267bool
268Lwo2Layer::_find_triangle_strips(PolygonsList& polygons, PolygonsList& triangle_strips)
269{
270  bool found = false;
271
272  while (_find_triangle_strip(polygons, triangle_strips))
273    {
274      found = true;
275    }
276
277  if (triangle_strips.size() > 0)
278    {
279      OSG_INFO << "LWO2 loader, optimizing: found " << triangle_strips.size() << " triangle strips" << endl;
280    }
281
282  return found;
283}
284
285bool
286Lwo2Layer::_find_triangle_fan(PolygonsList& polygons, PolygonsList& triangle_fans)
287{
288  bool found = false;
289  IteratorPolygonsList polygon_iterator = polygons.begin();
290  while (polygon_iterator != polygons.end())
291    {
292      PointsList& points_list = *polygon_iterator;
293      if (points_list.size() == 3 && points_list[0].point_index != -1)
294        {
295          PointData a = points_list[0];
296          PointData b = points_list[1];
297          PointData c = points_list[2];
298
299          int next_polygon_index = _find_triangle_begins_with(polygons, a, c);
300          while (next_polygon_index >= 0)
301            {
302              found = true;
303              PointData d = polygons[next_polygon_index][2];
304
305              PointsList point_list;
306              point_list.push_back(a);
307              point_list.push_back(b);
308              point_list.push_back(c);
309              point_list.push_back(d);
310
311              // delete second triangle (mark as deleted)
312              (*(polygons.begin() + next_polygon_index))[0].point_index = -1;
313
314              // delete current (first) triangle (mark as deleted)
315              (*polygon_iterator)[0].point_index = -1;
316
317              c = d;
318              while ((next_polygon_index = _find_triangle_begins_with(polygons, a, c)) >= 0)
319                {
320                  PointData d = polygons[next_polygon_index][2];
321                  point_list.push_back(d);
322
323                  // delete next triangle (mark as deleted)
324                  (*(polygons.begin() + next_polygon_index))[0].point_index = -1;
325
326                  c = d;
327                }
328
329              triangle_fans.push_back(point_list);
330            }
331        }
332      polygon_iterator++;
333    }
334  return found;
335}
336
337bool
338Lwo2Layer::_find_triangle_strip(PolygonsList& polygons, PolygonsList& triangle_strips)
339{
340  bool found = false;
341  IteratorPolygonsList polygon_iterator = polygons.begin();
342  int polygon_index = 0;
343  while (polygon_iterator != polygons.end())
344    {
345      PointsList& points_list = *polygon_iterator;
346      if (points_list.size() == 3 && points_list[0].point_index != -1)
347        {
348          PointData a = points_list[0];
349          PointData b = points_list[1];
350          PointData c = points_list[2];
351
352          int next_polygon_index = _find_triangle_begins_with(polygons, c, b);
353
354          while (next_polygon_index >= 0)
355            {
356              found = true;
357              PointData d = polygons[next_polygon_index][2];
358
359              PointsList point_list;
360              point_list.push_back(a);
361              point_list.push_back(b);
362              point_list.push_back(c);
363              point_list.push_back(d);
364
365              // delete second triangle (mark as deleted)
366              (*(polygons.begin() + next_polygon_index))[0].point_index = -1;
367
368              // delete current (first) triangle (mark as deleted)
369              (*polygon_iterator)[0].point_index = -1;
370
371              PointData strip_a = c;
372              PointData strip_b = d;
373              bool current_strip_a = true;
374
375              while ((next_polygon_index = _find_triangle_begins_with(polygons, strip_a, strip_b)) >= 0)
376                {
377                  PointData d = polygons[next_polygon_index][2];
378                  point_list.push_back(d);
379
380                  if (current_strip_a)
381                    {
382                      strip_a = d;
383                    }
384                  else
385                    {
386                      strip_b = d;
387                    }
388                  current_strip_a = !current_strip_a;
389
390                  // delete next triangle (mark as deleted)
391                  (*(polygons.begin() + next_polygon_index))[0].point_index = -1;
392                }
393
394              triangle_strips.push_back(point_list);
395            }
396        }
397      polygon_iterator++;
398      polygon_index++;
399    }
400  return found;
401}
402
403int
404Lwo2Layer::_find_triangle_begins_with(PolygonsList& polygons, PointData& a, PointData& b)
405{
406  int result = -1;
407
408  int polygon_index = 0;
409  for (IteratorPolygonsList polygon_iterator = polygons.begin(); polygon_iterator != polygons.end(); polygon_iterator++, polygon_index++)
410    {
411      PointsList& points_list = *polygon_iterator;
412      if (points_list.size() == 3 && points_list[0].point_index != -1)
413        {
414          if (points_list[0] == a && points_list[1] == b)
415            {
416              result = polygon_index;
417              break;
418            }
419          else if (points_list[1] == a && points_list[2] == b)
420            {
421              // shift points
422              PointData temp = points_list[0];
423              points_list[0] = points_list[1];
424              points_list[1] = points_list[2];
425              points_list[2] = temp;
426
427              result = polygon_index;
428              break;
429            }
430          else if (points_list[2] == a && points_list[0] == b)
431            {
432              // shift points
433              PointData temp = points_list[2];
434              points_list[2] = points_list[1];
435              points_list[1] = points_list[0];
436              points_list[0] = temp;
437
438              result = polygon_index;
439              break;
440            }
441        }
442    }
443  return result;
444}
Note: See TracBrowser for help on using the browser.