source: nanovis/trunk/ConvexPolygon.cpp @ 4596

Last change on this file since 4596 was 3611, checked in by ldelgass, 12 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.