source: trunk/vizservers/nanovis/ConvexPolygon.cpp @ 823

Last change on this file since 823 was 451, checked in by mmc, 18 years ago

Fixed a problem with two volumes of same size and shape, as we have
in the Quantum Dot Lab (wavefunction and geometry). One volume was
obscuring the other, since their slices sat at exactly the same point.

Dialed up the ambient lighting, so features would be visible even when
in shadow.

Fixed the gradient calculation to be symmetric, so features don't
get distorted in a particular direction.

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