117 |
virtual float nonlinearity(const ZPt &p, float radius) { |
virtual float nonlinearity(const ZPt &p, float radius) { |
118 |
return 0; |
return 0; |
119 |
} |
} |
120 |
|
virtual bool shouldBeDrawn() { |
121 |
|
return true; |
122 |
|
} |
123 |
}; |
}; |
124 |
|
|
125 |
/** Affine coordinate system (in xy), offset in z. |
/** Affine coordinate system (in xy), offset in z. |
285 |
*/ |
*/ |
286 |
class BuoyOnCircleCoords : public CoordSys { |
class BuoyOnCircleCoords : public CoordSys { |
287 |
ZVec tr; |
ZVec tr; |
288 |
|
CoordSys *anchor; |
289 |
public: |
public: |
290 |
BuoyOnCircleCoords() : tr() { } |
BuoyOnCircleCoords() : tr() { } |
291 |
BuoyOnCircleCoords(ZVec tr) : tr(tr) { } |
BuoyOnCircleCoords(ZVec tr) : tr(tr) { } |
292 |
enum { NParams = 6, NPrevious = 1 }; |
enum { NParams = 6, NPrevious = 2, NParents = 1 }; |
293 |
|
virtual void setSuper(CoordSys **super) { |
294 |
|
CoordSys::setSuper(super); |
295 |
|
this->anchor = super[1]; |
296 |
|
} |
297 |
virtual void setParams(float *params) { |
virtual void setParams(float *params) { |
298 |
float pointdir = params[5]; |
float pointdir = params[5]; |
299 |
ZVec ctr(params[0], params[1], 0); |
ZVec ctr(params[0], params[1], 0); |
306 |
} |
} |
307 |
|
|
308 |
// Get the anchor of the buoy |
// Get the anchor of the buoy |
309 |
ZPt anchor = super->transform(ZPt(0,0,0)); |
ZPt anchor = this->anchor->transform(ZPt(0,0,0)); |
310 |
// Now that we have the anchor, project |
// Now that we have the anchor, project |
311 |
// from it to the circle. |
// from it to the circle. |
312 |
ZVec amc = proj - ctr; amc.z = 0; |
ZVec amc = proj - ctr; amc.z = 0; |
349 |
glTranslatef(tr.x, tr.y, tr.z); |
glTranslatef(tr.x, tr.y, tr.z); |
350 |
return true; |
return true; |
351 |
} |
} |
352 |
|
virtual bool getOthertypeParams(int type, float *into) { |
353 |
|
// Parameter layout: x, y, depth, xx, xy, yx, yy |
354 |
|
if(type == 1) { // translation |
355 |
|
into[0] = tr.x; |
356 |
|
into[1] = tr.y; |
357 |
|
into[2] = tr.z; |
358 |
|
into[3] = 1; |
359 |
|
into[4] = 0; |
360 |
|
into[5] = 0; |
361 |
|
into[6] = 1; |
362 |
|
return true; |
363 |
|
} |
364 |
|
return false; |
365 |
|
} |
366 |
}; |
}; |
367 |
|
|
368 |
/** Rotation around 3D vector. |
/** Rotation around 3D vector. |
553 |
CoordSys::setSuper(super); |
CoordSys::setSuper(super); |
554 |
this->super2 = super[1]; |
this->super2 = super[1]; |
555 |
} |
} |
556 |
enum { NParams = 0, NPrevious = 2 } ; |
enum { NParams = 0, NPrevious = 2, NParents = 2 } ; |
557 |
virtual void setParams(float *params) { } |
virtual void setParams(float *params) { } |
558 |
virtual CoordSys *createInverse() { |
virtual CoordSys *createInverse() { |
559 |
return new ConcatCoordSys( super2->getInverse(), super->getInverse(), |
return new ConcatCoordSys( super2->getInverse(), super->getInverse(), |
580 |
if(!super2->performGL()) return false; |
if(!super2->performGL()) return false; |
581 |
return super->performGL(); |
return super->performGL(); |
582 |
} |
} |
583 |
|
virtual bool shouldBeDrawn() { |
584 |
|
return super->shouldBeDrawn() && super2->shouldBeDrawn(); |
585 |
|
} |
586 |
|
|
587 |
}; |
}; |
588 |
|
|
589 |
struct SomeFactory { |
struct SomeFactory { |
590 |
virtual int nparams() = 0; |
virtual int nparams() = 0; |
591 |
virtual int nprevious() = 0; |
virtual int nprevious() = 0; |
592 |
|
virtual int nparents() = 0; |
593 |
virtual CoordSys *create() = 0; |
virtual CoordSys *create() = 0; |
594 |
}; |
}; |
595 |
|
|
597 |
public: |
public: |
598 |
virtual int nparams() { return C::NParams; } |
virtual int nparams() { return C::NParams; } |
599 |
virtual int nprevious() { return 1; } |
virtual int nprevious() { return 1; } |
600 |
|
virtual int nparents() { return 1; } |
601 |
virtual CoordSys *create() { return new TransformCoordSys<C>(); } |
virtual CoordSys *create() { return new TransformCoordSys<C>(); } |
602 |
}; |
}; |
603 |
template<class C> class NoTransFactory : public SomeFactory { |
template<class C> class NoTransFactory : public SomeFactory { |
604 |
public: |
public: |
605 |
virtual int nparams() { return C::NParams; } |
virtual int nparams() { return C::NParams; } |
606 |
virtual int nprevious() { return C::NPrevious; } |
virtual int nprevious() { return C::NPrevious; } |
607 |
|
virtual int nparents() { return C::NParents; } |
608 |
virtual CoordSys *create() { return new C(); } |
virtual CoordSys *create() { return new C(); } |
609 |
}; |
}; |
610 |
|
|
627 |
0 |
0 |
628 |
}; |
}; |
629 |
|
|
630 |
|
bool canconvert[9][9] = { // [source][target] |
631 |
|
{ 1, 0, 0, 0, 0, 0, 0, 0, 0 }, |
632 |
|
{ 0, 1, 0, 0, 0, 0, 0, 0, 0 }, |
633 |
|
{ 0, 0, 1, 0, 0, 0, 0, 0, 0 }, |
634 |
|
{ 0, 0, 0, 1, 0, 0, 0, 0, 0 }, |
635 |
|
{ 0, 0, 0, 0, 1, 0, 0, 0, 0 }, |
636 |
|
{ 0, 0, 0, 0, 0, 1, 0, 0, 0 }, |
637 |
|
{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, |
638 |
|
{ 0, 1, 0, 0, 0, 0, 0, 1, 0 }, // buoyoncircle -> affine |
639 |
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 1 } |
640 |
|
}; |
641 |
|
|
642 |
int CoordSet::nprevious(int typecode) { |
int CoordSet::nprevious(int typecode) { |
643 |
return facs[typecode]->nprevious(); |
return facs[typecode]->nprevious(); |
644 |
} |
} |
671 |
cs[0] = new RootCoords(); |
cs[0] = new RootCoords(); |
672 |
DBG(dbg) << "setroot\n"; |
DBG(dbg) << "setroot\n"; |
673 |
int lastIndSize = 1; |
int lastIndSize = 1; |
674 |
|
|
675 |
|
CoordSet *cs1_tmp = 0; |
676 |
|
CoordSet *cs2_tmp = 0; |
677 |
|
|
678 |
for(int i=1; i<ninds; i+=lastIndSize) { |
for(int i=1; i<ninds; i+=lastIndSize) { |
679 |
DBG(dbg) << "loop "<<i<<"\n"; |
DBG(dbg) << "loop "<<i<<"\n"; |
680 |
int parind = params.size(); |
int parind = params.size(); |
687 |
lastIndSize = nprev + 2; // typecode, prevs and paramind |
lastIndSize = nprev + 2; // typecode, prevs and paramind |
688 |
|
|
689 |
CoordSys *prev[nprev]; |
CoordSys *prev[nprev]; |
|
|
|
|
for(int j=0; j<nprev; j++) { |
|
|
int parent = inds1[i+1+j]; |
|
|
CoordSys *parentcs = cs[parent]; |
|
|
if(parentcs == 0) { |
|
|
DBG(dbg) << "Parent "<<j<<" not interp\n"; |
|
|
goto nextInd; // If parent's not interpolating, neither are we. |
|
|
} |
|
|
prev[j] = parentcs; |
|
|
} |
|
690 |
|
|
691 |
ind1 = inds1[i+1+nprev]; |
ind1 = inds1[i+1+nprev]; |
692 |
csind2 = ((interpinds && i < interpinds[0]) ? interpinds[i] : -1); |
csind2 = ((interpinds && i < interpinds[0]) ? interpinds[i] : -1); |
693 |
DBG(dbg) << "inds: "<<parind<<" typ:"<<tp<<" npars:"<<npars<< |
DBG(dbg) << "inds: "<<parind<<" typ:"<<tp<<" npars:"<<npars<< |
694 |
" parent:"<<prev[0]<<" "<< |
" parent:"<<prev[0]<<" "<< |
695 |
" ind1:"<<ind1<<" "<<csind2<<"\n"; |
" ind1:"<<ind1<<" "<<csind2<<"\n"; |
696 |
|
|
697 |
|
|
698 |
if(csind2 <= 0) { |
if(csind2 <= 0) { |
699 |
if(show1) { |
if(show1) { |
700 |
for(int j = 0; j<npars; j++) { |
for(int j = 0; j<npars; j++) { |
704 |
continue; |
continue; |
705 |
} |
} |
706 |
} else { |
} else { |
707 |
int ind2 = inds2[csind2 + 2]; |
int t2 = inds2[csind2]; |
708 |
for(int j = 0; j<npars; j++) { |
int ind2 = inds2[csind2 + 1 + nprevious(t2)]; |
709 |
DBG(dbg) << "Interpolating "<<(ind1+j)<<" "<<(ind2+j)<<" = "<< |
if(t2 == tp) { |
710 |
points1[ind1+j]<<" "<< points2[ind2+j]<<"\n"; |
for(int j = 0; j<npars; j++) { |
711 |
params.push_back(lerp(points1[ind1 + j], points2[ind2 + j], fract)); |
DBG(dbg) << "Interpolating " |
712 |
|
<<(ind1+j)<<" " <<(ind2+j)<<" = " |
713 |
|
<< points1[ind1+j]<<" "<< points2[ind2+j]<<"\n"; |
714 |
|
params.push_back( |
715 |
|
lerp(points1[ind1 + j], |
716 |
|
points2[ind2 + j], fract)); |
717 |
|
} |
718 |
|
} else { |
719 |
|
// Now, the hairy case. |
720 |
|
DBG(dbg) << "It got hairy now: "<<tp<<" "<<t2<<"\n"; |
721 |
|
if(!cs1_tmp) { |
722 |
|
cs1_tmp = new CoordSet(); |
723 |
|
cs1_tmp->setPoints(ninds, inds1, points1, |
724 |
|
0, 0, 0, 0, true); |
725 |
|
} |
726 |
|
if(!cs2_tmp) { |
727 |
|
int maxind = 0; |
728 |
|
for(int k = 1; k<interpinds[0]; k++) |
729 |
|
if(interpinds[k] > maxind) |
730 |
|
maxind = interpinds[k]; |
731 |
|
cs2_tmp = new CoordSet(); |
732 |
|
cs2_tmp->setPoints(maxind+1, inds2, points2, 0, 0, 0, |
733 |
|
0, true); |
734 |
|
} |
735 |
|
CoordSys *cs1_non = cs1_tmp->get(i); |
736 |
|
CoordSys *cs2_non = cs2_tmp->get(csind2); |
737 |
|
// Next, the conversion. |
738 |
|
// For now, insist on one converting directly |
739 |
|
// to the other. Later need to search |
740 |
|
// inheritance tree |
741 |
|
int cs1_np = npars; |
742 |
|
int cs2_np = nparams(t2); |
743 |
|
// Just try each conversion routine; |
744 |
|
int maxpar = cs1_np >? cs2_np; // gnu c++-ism. |
745 |
|
float newpars[maxpar]; |
746 |
|
DBG(dbg) << "Try getOther: "<<maxpar<< |
747 |
|
" " << cs1_non << " " |
748 |
|
<< cs2_non << "\n"; |
749 |
|
if(cs1_non->getOthertypeParams(t2, newpars)) { |
750 |
|
DBG(dbg) << "Changed 1\n"; |
751 |
|
for(int i=0; i<cs2_np; i++) { |
752 |
|
DBG(dbg) << "Interp "<<newpars[i]<<" "<<points2[ind2+i]<<"\n"; |
753 |
|
params.push_back( |
754 |
|
lerp(newpars[i], |
755 |
|
points2[ind2 + i], |
756 |
|
fract)); |
757 |
|
} |
758 |
|
// NOTE!!! |
759 |
|
tp = t2; |
760 |
|
nprev = nprevious(tp); |
761 |
|
// Now, fall through, it gets created right. |
762 |
|
} else if(cs2_non->getOthertypeParams(tp, newpars)) { |
763 |
|
DBG(dbg) << "Changed 2\n"; |
764 |
|
for(int i=0; i<cs1_np; i++) { |
765 |
|
DBG(dbg) << "Interp "<<points1[ind1+i]<<" "<<newpars[i]<<" "<<"\n"; |
766 |
|
params.push_back( |
767 |
|
lerp(points1[ind1 + i], |
768 |
|
newpars[i], |
769 |
|
fract)); |
770 |
|
} |
771 |
|
// Fall through, it's the right type |
772 |
|
} |
773 |
|
DBG(dbg) << "Done getother: "<<tp<<"\n"; |
774 |
} |
} |
775 |
} |
} |
776 |
{ |
{ |
777 |
|
|
778 |
|
for(int j=0; j<nprev; j++) { |
779 |
|
int parent = inds1[i+1+j]; |
780 |
|
CoordSys *parentcs = cs[parent]; |
781 |
|
if(parentcs == 0) { |
782 |
|
DBG(dbg) << "Parent "<<j<<" not interp\n"; |
783 |
|
goto nextInd; // If parent's not interpolating, neither are we. |
784 |
|
} |
785 |
|
prev[j] = parentcs; |
786 |
|
} |
787 |
|
DBG(dbg) << "CS assigned "<<tp<<"\n"; |
788 |
|
|
789 |
CoordSys *c = create(tp); |
CoordSys *c = create(tp); |
790 |
cs[i] = c; |
cs[i] = c; |
791 |
c->setSuper(prev); |
c->setSuper(prev); |
793 |
} |
} |
794 |
nextInd:; |
nextInd:; |
795 |
} |
} |
796 |
|
if(cs1_tmp) delete cs1_tmp; |
797 |
|
if(cs2_tmp) delete cs2_tmp; |
798 |
DBG(dbg) << "end\n"; |
DBG(dbg) << "end\n"; |
799 |
} |
} |
800 |
|
|
801 |
bool CoordSys::performGL() { |
bool CoordSys::performGL() { |
802 |
DBG(dbg) << "Potential problem: performGL default implementation called, means incorrect rendering\n"; |
DBG(dbg) << "Potential problem: performGL default implementation" |
803 |
|
" called, means incorrect rendering\n"; |
804 |
return false; |
return false; |
805 |
} |
} |
806 |
CoordSys *CoordSys::createInverse() { |
CoordSys *CoordSys::createInverse() { |
807 |
DBG(dbg) << "Potential problem: createInverse default implementation called, means incorrect rendering\n"; |
DBG(dbg) << "Potential problem: createInverse default implementation" |
808 |
|
" called, means incorrect rendering\n"; |
809 |
return new RootCoords(); |
return new RootCoords(); |
810 |
} |
} |
811 |
|
|