source: branches/nanovis2/packages/vizservers/nanovis/ConvexPolygon.cpp @ 3351

Last change on this file since 3351 was 3305, checked in by ldelgass, 11 years ago

sync with trunk

  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1 /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * ----------------------------------------------------------------------
4 * ConvexPolygon.cpp: convex polygon class
5 *
6 * ======================================================================
7 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
8 *           Purdue Rendering and Perceptualization Lab (PURPL)
9 *
10 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
11 *
12 *  See the file "license.terms" for information on usage and
13 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 * ======================================================================
15 */
16#include <assert.h>
17
18#include <GL/glew.h>
19
20#include "ConvexPolygon.h"
21#include "Trace.h"
22
23ConvexPolygon::ConvexPolygon(VertexVector newvertices)
24{
25    vertices.insert(vertices.begin(), newvertices.begin(), newvertices.end());
26}
27
28void
29ConvexPolygon::transform(const Mat4x4& mat)
30{
31    VertexVector tmp = vertices;
32    vertices.clear();
33
34    for (unsigned int i = 0; i < tmp.size(); i++) {
35        Vector4 vec = tmp[i];
36        vertices.push_back(mat.transform(vec));
37    }
38}
39
40void
41ConvexPolygon::translate(const Vector4& shift)
42{
43    VertexVector tmp = vertices;
44    vertices.clear();
45
46    for (unsigned int i = 0; i < tmp.size(); i++) {
47        Vector4 vec = tmp[i];
48        vertices.push_back(vec+shift);
49    }
50}
51
52#define SIGN_DIFFERS(x, y) \
53    ( ((x) < 0.0 && (y) > 0.0) || ((x) > 0.0 && (y) < 0.0) )
54
55bool
56ConvexPolygon::clip(Plane& clipPlane, bool copyToTexcoord)
57{
58    if (vertices.size() == 0) {
59        ERROR("polygon has no vertices\n");
60        return false;
61    }
62
63    VertexVector clippedVerts;
64    clippedVerts.reserve(2 * vertices.size());
65
66    // The algorithm is as follows: for each vertex
67    // in the current poly, check to see which
68    // half space it is in: clipped (outside) or inside.
69    // If the previous vertex was in the other
70    // half space, find the intersection of that edge
71    // with the clip plane and add that intersection
72    // point to the new list of vertices.  If the
73    // current vertex is in the inside half-space,
74    // add it to the new list as well.
75
76    Vector4 plane = clipPlane.getCoeffs();
77
78    // This implementation is based on the Mesa 3D library (MIT license)
79    int v1 = 0;
80    // dot product >= 0 on/inside half-space, < 0 outside half-space
81    float dot1 = vertices[v1] * plane;
82    for (unsigned int i = 1; i <= vertices.size(); i++) {
83        int v2 = (i == vertices.size()) ? 0 : i;
84        float dot2 = vertices[v2] * plane;
85        if (dot1 >= 0.0) {
86            // on/inside
87            clippedVerts.push_back(vertices[v1]);
88        }
89        if (SIGN_DIFFERS(dot1, dot2)) {
90            if (dot1 < 0.0) {
91                // outside -> inside
92                double t = dot1 / (dot1 - dot2);
93                clippedVerts.push_back(vlerp(vertices[v1], vertices[v2], t));
94            } else {
95                // inside -> outside
96                double t = dot2 / (dot2 - dot1);
97                clippedVerts.push_back(vlerp(vertices[v2], vertices[v1], t));
98            }
99        }
100        dot1 = dot2;
101        v1 = v2;
102    }
103
104    vertices.clear();
105
106    if (clippedVerts.size() < 3) {
107        texcoords.clear();
108        return false;
109    } else {
110        vertices.insert(vertices.begin(),
111                        clippedVerts.begin(),
112                        clippedVerts.end());
113
114        if (copyToTexcoord)
115            copyVerticesToTexcoords();
116
117        return true;
118    }
119}
120
121#undef SIGN_DIFFERS
122
123void
124ConvexPolygon::copyVerticesToTexcoords()
125{
126    if (texcoords.size() > 0)
127        texcoords.clear();
128
129    for (unsigned int i = 0; i < vertices.size(); i++) {
130        texcoords.push_back(vertices[i]);
131    }
132}
133
134void
135ConvexPolygon::emit(bool useTexture)
136{
137    if (vertices.size() >= 3) {
138        for (unsigned int i = 0; i < vertices.size(); i++) {
139            if (useTexture) {
140                glTexCoord4fv((float *)&(texcoords[i]));
141                //glTexCoord4fv((float *)&(vertices[i]));
142            }
143            glVertex4fv((float *)&(vertices[i]));
144        }
145    } else {
146        WARN("No polygons to render\n");
147    }
148}
149
150void
151ConvexPolygon::emit(bool useTexture, const Vector3& shift, const Vector3& scale)
152{
153    if (vertices.size() >= 3) {
154        for (unsigned int i = 0; i < vertices.size(); i++) {
155            if (useTexture) {
156                glTexCoord4fv((float *)&(vertices[i]));
157            }
158            Vector4 tmp = (vertices[i]);
159            Vector4 shift_4d = Vector4(shift.x, shift.y, shift.z, 0);
160            tmp = tmp + shift_4d;
161            tmp.x = tmp.x * scale.x;
162            tmp.y = tmp.y * scale.y;
163            tmp.z = tmp.z * scale.z;
164            glVertex4fv((float *)(&tmp));
165        }
166    } else {
167        WARN("No polygons to render\n");
168    }
169}
Note: See TracBrowser for help on using the repository browser.