1 | /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
---|
2 | /* |
---|
3 | * Copyright (c) 2004-2013 HUBzero Foundation, LLC |
---|
4 | * |
---|
5 | * Authors: |
---|
6 | * Wei Qiao <qiaow@purdue.edu> |
---|
7 | * Insoo Woo <iwoo@purdue.edu> |
---|
8 | * George A. Howlett <gah@purdue.edu> |
---|
9 | * Leif Delgass <ldelgass@purdue.edu> |
---|
10 | */ |
---|
11 | |
---|
12 | #include <float.h> |
---|
13 | #include <assert.h> |
---|
14 | |
---|
15 | #include <vrmath/Vector3f.h> |
---|
16 | #include <vrmath/Vector4f.h> |
---|
17 | #include <vrmath/Matrix4x4d.h> |
---|
18 | |
---|
19 | #include "FlowBox.h" |
---|
20 | #include "Volume.h" |
---|
21 | #include "Trace.h" |
---|
22 | |
---|
23 | using namespace vrmath; |
---|
24 | |
---|
25 | FlowBox::FlowBox(const char *name) : |
---|
26 | _name(name) |
---|
27 | { |
---|
28 | _sv.isHidden = false; |
---|
29 | _sv.corner1.x = 0.0f; |
---|
30 | _sv.corner1.y = 0.0f; |
---|
31 | _sv.corner1.z = 0.0f; |
---|
32 | _sv.corner2.x = 1.0f; |
---|
33 | _sv.corner2.y = 1.0f; |
---|
34 | _sv.corner2.z = 1.0f; |
---|
35 | _sv.lineWidth = 1.2f; |
---|
36 | _sv.color.r = _sv.color.b = _sv.color.g = _sv.color.a = 1.0f; |
---|
37 | } |
---|
38 | |
---|
39 | FlowBox::~FlowBox() |
---|
40 | { |
---|
41 | TRACE("Freeing switches"); |
---|
42 | Rappture::FreeSwitches(_switches, &_sv, 0); |
---|
43 | } |
---|
44 | |
---|
45 | void |
---|
46 | FlowBox::getWorldSpaceBounds(Vector3f& bboxMin, |
---|
47 | Vector3f& bboxMax, |
---|
48 | const Volume *vol) const |
---|
49 | { |
---|
50 | bboxMin.set(FLT_MAX, FLT_MAX, FLT_MAX); |
---|
51 | bboxMax.set(-FLT_MAX, -FLT_MAX, -FLT_MAX); |
---|
52 | |
---|
53 | Vector3f origin = vol->location(); |
---|
54 | Vector3f scale = vol->getPhysicalScaling(); |
---|
55 | |
---|
56 | Matrix4x4d mat; |
---|
57 | mat.makeTranslation(origin); |
---|
58 | Matrix4x4d mat2; |
---|
59 | mat2.makeScale(scale); |
---|
60 | |
---|
61 | mat.multiply(mat2); |
---|
62 | |
---|
63 | Vector3f min, max; |
---|
64 | min.x = vol->xAxis.min(); |
---|
65 | min.y = vol->yAxis.min(); |
---|
66 | min.z = vol->zAxis.min(); |
---|
67 | max.x = vol->xAxis.max(); |
---|
68 | max.y = vol->yAxis.max(); |
---|
69 | max.z = vol->zAxis.max(); |
---|
70 | |
---|
71 | float x0, y0, z0, x1, y1, z1; |
---|
72 | x0 = y0 = z0 = 0.0f; |
---|
73 | x1 = y1 = z1 = 0.0f; |
---|
74 | if (max.x > min.x) { |
---|
75 | x0 = (_sv.corner1.x - min.x) / (max.x - min.x); |
---|
76 | x1 = (_sv.corner2.x - min.x) / (max.x - min.x); |
---|
77 | } |
---|
78 | if (max.y > min.y) { |
---|
79 | y0 = (_sv.corner1.y - min.y) / (max.y - min.y); |
---|
80 | y1 = (_sv.corner2.y - min.y) / (max.y - min.y); |
---|
81 | } |
---|
82 | if (max.z > min.z) { |
---|
83 | z0 = (_sv.corner1.z - min.z) / (max.z - min.z); |
---|
84 | z1 = (_sv.corner2.z - min.z) / (max.z - min.z); |
---|
85 | } |
---|
86 | |
---|
87 | TRACE("Box model bounds: (%g,%g,%g) - (%g,%g,%g)", |
---|
88 | x0, y0, z0, x1, y1, z1); |
---|
89 | |
---|
90 | Vector3f modelMin(x0, y0, z0); |
---|
91 | Vector3f modelMax(x1, y1, z1); |
---|
92 | |
---|
93 | Vector4f bvert[8]; |
---|
94 | bvert[0] = Vector4f(modelMin.x, modelMin.y, modelMin.z, 1); |
---|
95 | bvert[1] = Vector4f(modelMax.x, modelMin.y, modelMin.z, 1); |
---|
96 | bvert[2] = Vector4f(modelMin.x, modelMax.y, modelMin.z, 1); |
---|
97 | bvert[3] = Vector4f(modelMin.x, modelMin.y, modelMax.z, 1); |
---|
98 | bvert[4] = Vector4f(modelMax.x, modelMax.y, modelMin.z, 1); |
---|
99 | bvert[5] = Vector4f(modelMax.x, modelMin.y, modelMax.z, 1); |
---|
100 | bvert[6] = Vector4f(modelMin.x, modelMax.y, modelMax.z, 1); |
---|
101 | bvert[7] = Vector4f(modelMax.x, modelMax.y, modelMax.z, 1); |
---|
102 | |
---|
103 | for (int i = 0; i < 8; i++) { |
---|
104 | Vector4f worldVert = mat.transform(bvert[i]); |
---|
105 | if (worldVert.x < bboxMin.x) bboxMin.x = worldVert.x; |
---|
106 | if (worldVert.x > bboxMax.x) bboxMax.x = worldVert.x; |
---|
107 | if (worldVert.y < bboxMin.y) bboxMin.y = worldVert.y; |
---|
108 | if (worldVert.y > bboxMax.y) bboxMax.y = worldVert.y; |
---|
109 | if (worldVert.z < bboxMin.z) bboxMin.z = worldVert.z; |
---|
110 | if (worldVert.z > bboxMax.z) bboxMax.z = worldVert.z; |
---|
111 | } |
---|
112 | |
---|
113 | TRACE("Box world bounds: (%g,%g,%g) - (%g,%g,%g)", |
---|
114 | bboxMin.x, bboxMin.y, bboxMin.z, |
---|
115 | bboxMax.x, bboxMax.y, bboxMax.z); |
---|
116 | } |
---|
117 | |
---|
118 | void |
---|
119 | FlowBox::render(Volume *vol) |
---|
120 | { |
---|
121 | TRACE("Box: '%s'", _name.c_str()); |
---|
122 | |
---|
123 | glPushAttrib(GL_ENABLE_BIT); |
---|
124 | |
---|
125 | glEnable(GL_DEPTH_TEST); |
---|
126 | glDisable(GL_TEXTURE_2D); |
---|
127 | glDisable(GL_BLEND); |
---|
128 | |
---|
129 | glMatrixMode(GL_MODELVIEW); |
---|
130 | glPushMatrix(); |
---|
131 | |
---|
132 | Vector3f origin = vol->location(); |
---|
133 | glTranslatef(origin.x, origin.y, origin.z); |
---|
134 | |
---|
135 | Vector3f scale = vol->getPhysicalScaling(); |
---|
136 | glScalef(scale.x, scale.y, scale.z); |
---|
137 | |
---|
138 | Vector3f min, max; |
---|
139 | min.x = vol->xAxis.min(); |
---|
140 | min.y = vol->yAxis.min(); |
---|
141 | min.z = vol->zAxis.min(); |
---|
142 | max.x = vol->xAxis.max(); |
---|
143 | max.y = vol->yAxis.max(); |
---|
144 | max.z = vol->zAxis.max(); |
---|
145 | |
---|
146 | TRACE("box is %g,%g %g,%g %g,%g", |
---|
147 | _sv.corner1.x, _sv.corner2.x, |
---|
148 | _sv.corner1.y, _sv.corner2.y, |
---|
149 | _sv.corner1.z, _sv.corner2.z); |
---|
150 | TRACE("world is %g,%g %g,%g %g,%g", |
---|
151 | min.x, max.x, min.y, max.y, min.z, max.z); |
---|
152 | |
---|
153 | float x0, y0, z0, x1, y1, z1; |
---|
154 | x0 = y0 = z0 = 0.0f; |
---|
155 | x1 = y1 = z1 = 0.0f; |
---|
156 | if (max.x > min.x) { |
---|
157 | x0 = (_sv.corner1.x - min.x) / (max.x - min.x); |
---|
158 | x1 = (_sv.corner2.x - min.x) / (max.x - min.x); |
---|
159 | } |
---|
160 | if (max.y > min.y) { |
---|
161 | y0 = (_sv.corner1.y - min.y) / (max.y - min.y); |
---|
162 | y1 = (_sv.corner2.y - min.y) / (max.y - min.y); |
---|
163 | } |
---|
164 | if (max.z > min.z) { |
---|
165 | z0 = (_sv.corner1.z - min.z) / (max.z - min.z); |
---|
166 | z1 = (_sv.corner2.z - min.z) / (max.z - min.z); |
---|
167 | } |
---|
168 | TRACE("box bounds: %g,%g %g,%g %g,%g", |
---|
169 | x0, x1, y0, y1, z0, z1); |
---|
170 | |
---|
171 | glColor4d(_sv.color.r, _sv.color.g, _sv.color.b, _sv.color.a); |
---|
172 | glLineWidth(_sv.lineWidth); |
---|
173 | glBegin(GL_LINE_LOOP); |
---|
174 | { |
---|
175 | glVertex3d(x0, y0, z0); |
---|
176 | glVertex3d(x1, y0, z0); |
---|
177 | glVertex3d(x1, y1, z0); |
---|
178 | glVertex3d(x0, y1, z0); |
---|
179 | } |
---|
180 | glEnd(); |
---|
181 | glBegin(GL_LINE_LOOP); |
---|
182 | { |
---|
183 | glVertex3d(x0, y0, z1); |
---|
184 | glVertex3d(x1, y0, z1); |
---|
185 | glVertex3d(x1, y1, z1); |
---|
186 | glVertex3d(x0, y1, z1); |
---|
187 | } |
---|
188 | glEnd(); |
---|
189 | |
---|
190 | glBegin(GL_LINE_LOOP); |
---|
191 | { |
---|
192 | glVertex3d(x0, y0, z0); |
---|
193 | glVertex3d(x0, y0, z1); |
---|
194 | glVertex3d(x0, y1, z1); |
---|
195 | glVertex3d(x0, y1, z0); |
---|
196 | } |
---|
197 | glEnd(); |
---|
198 | |
---|
199 | glBegin(GL_LINE_LOOP); |
---|
200 | { |
---|
201 | glVertex3d(x1, y0, z0); |
---|
202 | glVertex3d(x1, y0, z1); |
---|
203 | glVertex3d(x1, y1, z1); |
---|
204 | glVertex3d(x1, y1, z0); |
---|
205 | } |
---|
206 | glEnd(); |
---|
207 | |
---|
208 | glPopMatrix(); |
---|
209 | glPopAttrib(); |
---|
210 | |
---|
211 | assert(CheckGL(AT)); |
---|
212 | } |
---|