source: trunk/packages/vizservers/nanovis/ConvexPolygon.cpp @ 1522

Last change on this file since 1522 was 978, checked in by gah, 16 years ago
File size: 5.4 KB
Line 
1 
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-2006  Purdue Research Foundation
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 "ConvexPolygon.h"
17#include <GL/gl.h>
18#include <assert.h>
19
20ConvexPolygon::ConvexPolygon(){}
21
22ConvexPolygon::ConvexPolygon(VertexVector newvertices){
23    vertices.insert(vertices.begin(), newvertices.begin(), newvertices.end());
24}
25
26// Finds the intersection of the line through
27// p1 and p2 with the given plane, putting the
28// result in intersect.
29//
30// If the line lies in the plane, an arbitrary
31// point on the line is returned.
32//
33// http://astronomy.swin.edu.au/pbourke/geometry/planeline/
34bool
35findIntersection(Vector4 p1, Vector4 p2, Vector4 plane, Vector4 &ret){
36    float a = plane.x;
37    float b = plane.y;
38    float c = plane.z;
39    float d = plane.w;
40
41    p1.perspective_devide();
42    float x1 = p1.x;
43    float y1 = p1.y;
44    float z1 = p1.z;
45
46    p2.perspective_devide();
47    float x2 = p2.x;
48    float y2 = p2.y;
49    float z2 = p2.z;
50
51    float uDenom = a * (x1 - x2) + b * (y1 - y2) + c * (z1 - z2);
52    float uNumer = a * x1 + b * y1 + c * z1 + d;
53
54    if (uDenom == 0){
55        //plane parallel to line
56        fprintf(stderr, "Unexpected code path: ConvexPolygon.cpp\n");
57        if (uNumer == 0){
58            for (int i = 0; i < 4; i++)
59                ret < p1;
60            return true;
61        }
62        return false;
63    }
64
65    float u = uNumer / uDenom;
66    ret.x = x1 + u * (x2 - x1);
67    ret.y = y1 + u * (y2 - y1);
68    ret.z = z1 + u * (z2 - z1);
69    ret.w = 1;
70    return true;
71}
72
73void
74ConvexPolygon::transform(Mat4x4 mat){
75    VertexVector tmp = vertices;
76    vertices.clear();
77
78    for (unsigned int i = 0; i < tmp.size(); i++) {
79        Vector4 vec = tmp[i];
80        vertices.push_back(mat.transform(vec));
81    }
82}
83
84
85void
86ConvexPolygon::translate(Vector4 shift){
87    VertexVector tmp = vertices;
88    vertices.clear();
89
90    for (unsigned int i = 0; i < tmp.size(); i++) {
91        Vector4 vec = tmp[i];
92        vertices.push_back(vec+shift);
93    }
94}
95
96void
97ConvexPolygon::clip(Plane &clipPlane, bool copy_to_texcoord) {
98    if (vertices.size() == 0) {
99        //fprintf(stderr, "ConvexPolygon: polygon has no vertices\n"); 
100        return;
101    }
102   
103    VertexVector clippedVerts;
104    clippedVerts.reserve(2 * vertices.size());
105
106    // The algorithm is as follows: for each vertex
107    // in the current poly, check to see which
108    // half space it is in: clipped or retained.
109    // If the previous vertex was in the other
110    // half space, find the intersect of that edge
111    // with the clip plane and add that intersect
112    // point to the new list of vertices.  If the
113    // current vertex is in the retained half-space,
114    // add it to the new list as well.
115
116    Vector4 intersect;
117    Vector4 plane = clipPlane.get_coeffs();
118
119    bool prevRetained = is_retained(vertices[0], plane);
120    if (prevRetained)
121        clippedVerts.push_back(vertices[0]);
122
123    for (unsigned int i = 1; i < vertices.size(); i++) {
124        bool retained = is_retained(vertices[i], plane);
125        if (retained != prevRetained) {
126            bool found = findIntersection(vertices[i - 1], vertices[i],
127                                          plane, intersect);
128            assert(found);
129            clippedVerts.push_back(intersect);
130        }
131        if (retained) {
132            clippedVerts.push_back(vertices[i]);
133        }
134        prevRetained = retained;
135    }
136
137    bool retained = is_retained(vertices[0], plane);
138    if (retained != prevRetained) {
139        bool found = findIntersection(vertices[vertices.size() - 1],
140                                      vertices[0], plane, intersect);
141        assert(found);
142        clippedVerts.push_back(intersect);
143    }
144
145    vertices.clear();
146    vertices.insert(vertices.begin(),
147                    clippedVerts.begin(),
148                    clippedVerts.end());
149
150    if(copy_to_texcoord)
151        copy_vertices_to_texcoords();
152}
153
154void
155ConvexPolygon::copy_vertices_to_texcoords(){
156    if(texcoords.size()>0)
157        texcoords.clear();
158
159    for (unsigned int i=0; i<vertices.size(); i++) {
160        texcoords.push_back(vertices[i]);
161    }
162}
163
164void
165ConvexPolygon::Emit(bool use_texture)
166{
167    if (vertices.size() >= 3) {
168        for (unsigned int i = 0; i<vertices.size(); i++) {
169            if(use_texture) {
170                glTexCoord4fv((float *)&(texcoords[i]));
171                //glTexCoord4fv((float *)&(vertices[i]));
172            }
173            glVertex4fv((float *)&(vertices[i]));
174            /*
175            //debug
176            fprintf(stderr, "(%f %f %f %f)",
177            vertices[i].x,
178            vertices[i].y,
179            vertices[i].z,
180            vertices[i].w );
181            */
182        }
183    }
184    //fprintf(stderr, " ");
185}
186
187
188void
189ConvexPolygon::Emit(bool use_texture, Vector3& shift, Vector3& scale)
190{
191    if (vertices.size() >= 3) {
192        for (unsigned int i = 0; i<vertices.size(); i++) {
193            if(use_texture) {
194                glTexCoord4fv((float *)&(vertices[i]));
195            }
196            Vector4 tmp = (vertices[i]);
197            Vector4 shift_4d = Vector4(shift.x, shift.y, shift.z, 0);
198            tmp = tmp + shift_4d;
199            tmp.x = tmp.x * scale.x;
200            tmp.y = tmp.y * scale.y;
201            tmp.z = tmp.z * scale.z;
202            glVertex4fv((float *)(&tmp));
203        }
204    }
205}
Note: See TracBrowser for help on using the repository browser.