source: nanovis/trunk/ConvexPolygon.cpp @ 5303

Last change on this file since 5303 was 3611, checked in by ldelgass, 7 years ago

Use nv namespace for classes in nanovis rather than prefixing class names with
Nv (still need to convert shader classes).

  • Property svn:eol-style set to native
File size: 4.6 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-2013  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
23using namespace nv;
24using namespace vrmath;
25
26ConvexPolygon::ConvexPolygon(VertexVector newvertices)
27{
28    vertices.insert(vertices.begin(), newvertices.begin(), newvertices.end());
29}
30
31void
32ConvexPolygon::transform(const Matrix4x4d& mat)
33{
34    VertexVector tmp = vertices;
35    vertices.clear();
36
37    for (unsigned int i = 0; i < tmp.size(); i++) {
38        Vector4f vec = tmp[i];
39        vertices.push_back(mat.transform(vec));
40    }
41}
42
43void
44ConvexPolygon::translate(const Vector4f& shift)
45{
46    VertexVector tmp = vertices;
47    vertices.clear();
48
49    for (unsigned int i = 0; i < tmp.size(); i++) {
50        Vector4f vec = tmp[i];
51        vertices.push_back(vec + shift);
52    }
53}
54
55#define SIGN_DIFFERS(x, y) \
56    ( ((x) < 0.0 && (y) > 0.0) || ((x) > 0.0 && (y) < 0.0) )
57
58bool
59ConvexPolygon::clip(nv::Plane& clipPlane, bool copyToTexcoord)
60{
61    if (vertices.size() == 0) {
62        ERROR("polygon has no vertices");
63        return false;
64    }
65
66    VertexVector clippedVerts;
67    clippedVerts.reserve(2 * vertices.size());
68
69    // The algorithm is as follows: for each vertex
70    // in the current poly, check to see which
71    // half space it is in: clipped (outside) or inside.
72    // If the previous vertex was in the other
73    // half space, find the intersection of that edge
74    // with the clip plane and add that intersection
75    // point to the new list of vertices.  If the
76    // current vertex is in the inside half-space,
77    // add it to the new list as well.
78
79    Vector4f plane = clipPlane.getCoeffs();
80
81    // This implementation is based on the Mesa 3D library (MIT license)
82    int v1 = 0;
83    // dot product >= 0 on/inside half-space, < 0 outside half-space
84    float dot1 = vertices[v1] * plane;
85    for (unsigned int i = 1; i <= vertices.size(); i++) {
86        int v2 = (i == vertices.size()) ? 0 : i;
87        float dot2 = vertices[v2] * plane;
88        if (dot1 >= 0.0) {
89            // on/inside
90            clippedVerts.push_back(vertices[v1]);
91        }
92        if (SIGN_DIFFERS(dot1, dot2)) {
93            if (dot1 < 0.0) {
94                // outside -> inside
95                double t = dot1 / (dot1 - dot2);
96                clippedVerts.push_back(vlerp(vertices[v1], vertices[v2], t));
97            } else {
98                // inside -> outside
99                double t = dot2 / (dot2 - dot1);
100                clippedVerts.push_back(vlerp(vertices[v2], vertices[v1], t));
101            }
102        }
103        dot1 = dot2;
104        v1 = v2;
105    }
106
107    vertices.clear();
108
109    if (clippedVerts.size() < 3) {
110        texcoords.clear();
111        return false;
112    } else {
113        vertices.insert(vertices.begin(), 
114                        clippedVerts.begin(),
115                        clippedVerts.end());
116
117        if (copyToTexcoord)
118            copyVerticesToTexcoords();
119
120        return true;
121    }
122}
123
124#undef SIGN_DIFFERS
125
126void
127ConvexPolygon::copyVerticesToTexcoords()
128{
129    if (texcoords.size() > 0)
130        texcoords.clear();
131
132    for (unsigned int i = 0; i < vertices.size(); i++) {
133        texcoords.push_back(vertices[i]);
134    }
135}
136
137void
138ConvexPolygon::emit(bool useTexture)
139{
140    if (vertices.size() >= 3) {
141        for (unsigned int i = 0; i < vertices.size(); i++) {
142            if (useTexture) {
143                glTexCoord4fv((float *)&(texcoords[i]));
144                //glTexCoord4fv((float *)&(vertices[i]));
145            }
146            glVertex4fv((float *)&(vertices[i]));
147        }
148    } else {
149        WARN("No polygons to render");
150    }
151}
152
153void 
154ConvexPolygon::emit(bool useTexture, const Vector3f& shift, const Vector3f& scale) 
155{
156    if (vertices.size() >= 3) {
157        for (unsigned int i = 0; i < vertices.size(); i++) {
158            if (useTexture) {
159                glTexCoord4fv((float *)&(vertices[i]));
160            }
161            Vector4f tmp = (vertices[i]);
162            Vector4f shift_4d = Vector4f(shift.x, shift.y, shift.z, 0);
163            tmp = tmp + shift_4d;
164            tmp.x = tmp.x * scale.x;
165            tmp.y = tmp.y * scale.y;
166            tmp.z = tmp.z * scale.z;
167            glVertex4fv((float *)(&tmp));
168        }
169    } else {
170        WARN("No polygons to render");
171    }
172}
Note: See TracBrowser for help on using the repository browser.