1 |
// (c) Tuomas J. Lukka and Asko Soukka |
// (c) Tuomas J. Lukka and Asko Soukka |
2 |
|
|
3 |
#include <Vob/Coorder.hxx> |
#include <vob/Coorder.hxx> |
4 |
|
#include <vob/VecGL.hxx> |
5 |
|
|
6 |
#define DBG(cname) if(!cname);else (std::cout << "CallGL: ") |
#define DBG(cname) if(!cname);else (std::cout << "CallGL: ") |
7 |
|
|
8 |
|
static bool dbg; |
9 |
|
|
10 |
namespace Vob { |
namespace Vob { |
11 |
|
|
12 |
Coorder::Coorder() : cs1_tmp(0), cs2_tmp(0) { |
/** A transform that interpolates between |
13 |
|
* two transforms pointwise. |
14 |
|
*/ |
15 |
|
struct PointInterpTransform : public Transform { |
16 |
|
const Transform &cs1, &cs2; |
17 |
|
float fract; |
18 |
|
bool didGetMat; |
19 |
|
float mat[16]; |
20 |
|
Transform *inv; |
21 |
|
|
22 |
|
PointInterpTransform(const Transform &cs1, const Transform &cs2, |
23 |
|
float fract) |
24 |
|
: cs1(cs1), cs2(cs2), fract(fract), inv(0) { } |
25 |
|
virtual void vertex(const ZPt &p) const { |
26 |
|
glVertex(transform(p)); |
27 |
|
} |
28 |
|
virtual ZPt transform(const ZPt &p) const { |
29 |
|
ZPt res = lerp(cs1.transform(p), |
30 |
|
cs2.transform(p), |
31 |
|
fract); |
32 |
|
DBG(dbg) << "PointInterp: "<<p<<": "<<fract<<" "<< |
33 |
|
cs1.transform(p) << " " << cs2.transform(p) << " " |
34 |
|
<< res<<"\n"; |
35 |
|
return res; |
36 |
|
} |
37 |
|
virtual float nonlinearity(const ZPt &p, float radius) const { |
38 |
|
return lerp(cs1.nonlinearity(p, radius), |
39 |
|
cs2.nonlinearity(p, radius), fract); |
40 |
|
} |
41 |
|
virtual void dump(std::ostream &out) const { |
42 |
|
out << "Pointinterp\n"; |
43 |
|
}; |
44 |
|
|
45 |
|
virtual bool shouldBeDrawn() const { |
46 |
|
return cs1.shouldBeDrawn() && cs2.shouldBeDrawn(); |
47 |
|
} |
48 |
|
virtual Pt getSqSize() const { |
49 |
|
return lerp(cs1.getSqSize(), cs2.getSqSize(), fract); |
50 |
|
} |
51 |
|
|
52 |
|
bool canPerformGL() const { |
53 |
|
return cs1.canPerformGL() && cs2.canPerformGL(); |
54 |
|
} |
55 |
|
|
56 |
|
void getMat() const { |
57 |
|
if(didGetMat) return; |
58 |
|
|
59 |
|
GLfloat mat1[16], mat2[16]; |
60 |
|
glPushAttrib(GL_TRANSFORM_BIT); |
61 |
|
glMatrixMode(GL_MODELVIEW); |
62 |
|
glPushMatrix(); |
63 |
|
|
64 |
|
glLoadIdentity(); |
65 |
|
cs1.performGL(); |
66 |
|
glGetFloatv(GL_MODELVIEW_MATRIX, mat1); |
67 |
|
|
68 |
|
glLoadIdentity(); |
69 |
|
cs2.performGL(); |
70 |
|
glGetFloatv(GL_MODELVIEW_MATRIX, mat2); |
71 |
|
|
72 |
|
DBG(dbg) << "PointInterp PerformGL!\n"; |
73 |
|
if(dbg) { |
74 |
|
for(int i=0; i<16; i++) DBG(dbg) << mat1[i] << " "; |
75 |
|
DBG(dbg) << "\n"; |
76 |
|
for(int i=0; i<16; i++) DBG(dbg) << mat2[i] << " "; |
77 |
|
DBG(dbg) << "\n"; |
78 |
|
} |
79 |
|
for(int i=0; i<16; i++) |
80 |
|
((float *)mat)[i] = lerp(mat1[i], mat2[i], fract); |
81 |
|
|
82 |
|
|
83 |
|
glPopMatrix(); |
84 |
|
glPopAttrib(); |
85 |
|
|
86 |
|
|
87 |
|
} |
88 |
|
|
89 |
|
|
90 |
|
bool performGL() const { |
91 |
|
// XXX Allow using of vertex weighting or something |
92 |
|
if(!canPerformGL()) return false; |
93 |
|
getMat(); |
94 |
|
glMultMatrixf(mat); |
95 |
|
return true; |
96 |
|
} |
97 |
|
const Transform &getInverse() const { |
98 |
|
/* |
99 |
|
if(canPerformGL()) { |
100 |
|
getMat(); |
101 |
|
return new MatrixCoordSys(invertMat(mat)); |
102 |
|
} else { |
103 |
|
*/ |
104 |
|
// Badly wrong |
105 |
|
if(inv == 0) |
106 |
|
((PointInterpTransform *)this)->inv = new PointInterpTransform(cs1.getInverse(), cs2.getInverse(), fract); |
107 |
|
return *inv; |
108 |
|
} |
109 |
|
}; |
110 |
|
|
111 |
|
|
112 |
|
Coorder::Coorder(TransformFactory fac) : |
113 |
|
transformFactory(fac), cs1_tmp(0), cs2_tmp(0) { |
114 |
} |
} |
115 |
Coorder::~Coorder() { |
Coorder::~Coorder() { |
116 |
DBG(dbg) << "Deleting coordset "<<this<<" "<<cs1_tmp<<" "<<cs2_tmp<<"\n"; |
DBG(dbg) << "Deleting coordset "<<this<<" "<<cs1_tmp<<" "<<cs2_tmp<<"\n"; |
177 |
|
|
178 |
int tp = inds1[i] & ~CSFLAGS; |
int tp = inds1[i] & ~CSFLAGS; |
179 |
|
|
180 |
int npars = nparams(tp); |
Transform *c = 0; |
181 |
int nprev = nprevious(tp); |
// Used as a temp; set to null if moved to c. |
182 |
|
Primitives::HierarchicalTransform *tmp_c; |
183 |
|
tmp_c = transformFactory(tp); |
184 |
|
if(!tmp_c) abort(); |
185 |
|
|
186 |
|
int npars = tmp_c->getNParams(); |
187 |
|
int nprev = tmp_c->getNDepends(); |
188 |
int ind1; |
int ind1; |
189 |
int csind2; |
int csind2; |
190 |
|
|
196 |
DBG(dbg) << "inds: "<<parind<<" typ:"<<tp<<" npars:"<<npars<< |
DBG(dbg) << "inds: "<<parind<<" typ:"<<tp<<" npars:"<<npars<< |
197 |
" ind1:"<<ind1<<" "<<csind2<<"\n"; |
" ind1:"<<ind1<<" "<<csind2<<"\n"; |
198 |
|
|
199 |
Transform *c; |
|
200 |
int t2 = 0; |
int t2 = 0; |
201 |
int ind2 = 0; |
int ind2 = 0; |
202 |
if(csind2 > 0) { |
if(csind2 > 0) { |
203 |
t2 = inds2[csind2] & ~CSFLAGS; |
t2 = inds2[csind2] & ~CSFLAGS; |
204 |
ind2 = inds2[csind2 + 1 + nprevious(t2)]; |
if(t2 != tp) goto interpolatePointwise; |
205 |
|
ind2 = inds2[csind2 + 1 + nprev]; // same as cs1 |
206 |
} |
} |
207 |
// We need to interpolate. Check the structural constraints: |
// We need to interpolate. Check the structural constraints: |
208 |
// If |
// If |
231 |
points2[ind2 + j], fract)); |
points2[ind2 + j], fract)); |
232 |
} |
} |
233 |
} |
} |
234 |
Transform *prev[nprev]; |
const Transform *prev[nprev]; |
235 |
|
|
236 |
for(int j=0; j<nprev; j++) { |
for(int j=0; j<nprev; j++) { |
237 |
int parent = inds1[i+1+j]; |
int parent = inds1[i+1+j]; |
248 |
* params. If the initialized coordsys (according to its initialized attributes) |
* params. If the initialized coordsys (according to its initialized attributes) |
249 |
* decides not to be drawn, it will be deleted and replaced with the NULL pointer. |
* decides not to be drawn, it will be deleted and replaced with the NULL pointer. |
250 |
*/ |
*/ |
251 |
c = create(tp); |
tmp_c->setParams(prev, &(params[0]) + parind); |
252 |
c->setSuper(prev); |
c = tmp_c; |
253 |
c->setParams(&(params[0]) + parind); |
tmp_c = 0; |
254 |
} else { |
} else { |
255 |
|
interpolatePointwise: |
256 |
// Now, the hairy case. |
// Now, the hairy case. |
257 |
DBG(dbg) << "It got hairy now: "<<tp<<" "<<t2<<"\n"; |
DBG(dbg) << "It got hairy now: "<<tp<<" "<<t2<<"\n"; |
258 |
if(!cs1_tmp) { |
if(!cs1_tmp) { |
259 |
cs1_tmp = new Coorder(); |
cs1_tmp = new Coorder(transformFactory); |
260 |
cs1_tmp->setPoints(ninds, inds1, points1, |
cs1_tmp->setPoints(ninds, inds1, points1, |
261 |
0, 0, 0, 0, true); |
0, 0, 0, 0, true); |
262 |
} |
} |
265 |
for(int k = 1; k<interpinds[0]; k++) |
for(int k = 1; k<interpinds[0]; k++) |
266 |
if(interpinds[k] > maxind) |
if(interpinds[k] > maxind) |
267 |
maxind = interpinds[k]; |
maxind = interpinds[k]; |
268 |
cs2_tmp = new Coorder(); |
cs2_tmp = new Coorder(transformFactory); |
269 |
cs2_tmp->setPoints(maxind+1, inds2, points2, 0, 0, 0, |
cs2_tmp->setPoints(maxind+1, inds2, points2, 0, 0, 0, |
270 |
0, true); |
0, true); |
271 |
} |
} |
274 |
|
|
275 |
if(!cs1_non || !cs2_non) goto nextInd; |
if(!cs1_non || !cs2_non) goto nextInd; |
276 |
|
|
277 |
c = new PointInterpCoordSys(cs1_non, cs2_non, fract); |
c = new PointInterpTransform(*cs1_non, *cs2_non, fract); |
278 |
|
|
279 |
} |
} |
280 |
{ |
{ |
286 |
cs[i] = NULL; |
cs[i] = NULL; |
287 |
} |
} |
288 |
} |
} |
289 |
nextInd:; |
nextInd: |
290 |
|
if(tmp_c) delete tmp_c; |
291 |
} |
} |
292 |
DBG(dbg) << "end: "<<cs1_tmp<<" "<<cs2_tmp<<"\n"; |
DBG(dbg) << "end: "<<cs1_tmp<<" "<<cs2_tmp<<"\n"; |
293 |
} |
} |