root/OpenSceneGraph/trunk/src/osgPlugins/lwo/Tessellator.cpp @ 11829

Revision 11829, 3.4 kB (checked in by robert, 4 years ago)

Introduced osg namespace to new local GLU functions

  • 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 "Tessellator.h"
9
10using namespace lwosg;
11
12namespace lwosg
13{
14
15    void CALLBACK cb_begin_data(GLenum type, void *data)
16    {
17        Tessellator *tess = static_cast<Tessellator *>(data);
18        tess->prim_type_ = type;
19        tess->incoming_.clear();
20    }
21
22    void CALLBACK cb_vertex_data(void *vertex_data, void *data)
23    {
24        Tessellator *tess = static_cast<Tessellator *>(data);
25        tess->incoming_.push_back(*static_cast<int *>(vertex_data));
26    }
27
28    void CALLBACK cb_end_data(void *data)
29    {
30        Tessellator *tess = static_cast<Tessellator *>(data);
31        tess->finalize_primitive();
32    }
33
34    void CALLBACK cb_error_data(GLenum error, void *data)
35    {
36        Tessellator *tess = static_cast<Tessellator *>(data);
37        tess->last_error_ = error;
38    }
39
40}
41
42bool Tessellator::tessellate(const Polygon &poly, const osg::Vec3Array *points, osg::DrawElementsUInt *out, const std::vector<int> *remap)
43{
44    out_ = out;
45    last_error_ = 0;
46
47    osg::GLUtesselator *tess = osg::gluNewTess();
48
49    osg::gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (osg::GLU_TESS_CALLBACK) (cb_begin_data));
50    osg::gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (osg::GLU_TESS_CALLBACK) (cb_vertex_data));
51    osg::gluTessCallback(tess, GLU_TESS_END_DATA, (osg::GLU_TESS_CALLBACK) (cb_end_data));
52    osg::gluTessCallback(tess, GLU_TESS_ERROR_DATA, (osg::GLU_TESS_CALLBACK) (cb_error_data));
53
54    osg::gluTessBeginPolygon(tess, this);
55    osg::gluTessBeginContour(tess);   
56
57    double *vertices = new double[poly.indices().size() * 3];
58    int *indices = new int[poly.indices().size()];
59
60    double *v = vertices;
61    int *x = indices;
62    for (Polygon::Index_list::const_iterator i=poly.indices().begin(); i!=poly.indices().end(); ++i, v+=3, ++x) {
63        const osg::Vec3 &P = (*points)[*i];
64        v[0] = P.x();
65        v[1] = P.y();
66        v[2] = P.z();
67        if (remap) {
68            *x = (*remap)[*i];
69        } else {
70            *x = *i;
71        }
72        gluTessVertex(tess, v, x);
73    }
74
75    osg::gluTessEndContour(tess);
76    osg::gluTessEndPolygon(tess);
77    osg::gluDeleteTess(tess);
78
79    delete[] vertices;
80    delete[] indices;
81
82    return last_error_ == 0;
83}
84
85Tessellator::~Tessellator()
86{
87}
88
89void Tessellator::finalize_primitive()
90{
91    if (incoming_.size() < 3) return;
92
93    if (prim_type_ == GL_TRIANGLES) {
94        for (Index_list::const_iterator i=incoming_.begin(); i!=incoming_.end(); ++i) {
95            out_->push_back(*i);
96        }
97    }
98
99    if (prim_type_ == GL_TRIANGLE_FAN) {
100        for (Index_list::const_iterator i=incoming_.begin()+1; (i+1)!=incoming_.end(); ++i) {
101            out_->push_back(incoming_.front());
102            out_->push_back(*i);
103            out_->push_back(*(i+1));
104        }
105    }
106
107    if (prim_type_ == GL_TRIANGLE_STRIP) {
108        int j = 0;
109        for (Index_list::const_iterator i=incoming_.begin(); (i+2)!=incoming_.end(); ++i, ++j) {
110            if ((j % 2) == 0) {
111                out_->push_back(*i);
112                out_->push_back(*(i+1));
113                out_->push_back(*(i+2));
114            } else {
115                out_->push_back(*i);
116                out_->push_back(*(i+2));
117                out_->push_back(*(i+1));
118            }
119        }
120    }
121}
Note: See TracBrowser for help on using the browser.