1 |
#include "libutil/Debug.hxx" |
#include "libutil/Debug.hxx" |
2 |
#include "libfisheye/Fisheye.hxx" |
#include "libfisheye/Fisheye.hxx" |
3 |
#include "Coords.hxx" |
#include "Coords.hxx" |
4 |
|
#include <GL/gl.h> |
5 |
|
|
6 |
namespace Coords { |
namespace Coords { |
7 |
DBGVAR(dbg, "Coords.general"); |
DBGVAR(dbg, "Coords.general"); |
8 |
DBGVAR(dbg_buoy, "Coords.buoy"); |
DBGVAR(dbg_buoy, "Coords.buoy"); |
9 |
|
DBGVAR(dbg_cull, "Coords.culling"); |
10 |
|
|
11 |
// The (STL-like) concept of transform: |
// The (STL-like) concept of transform: |
12 |
// enum { NParams = n }; |
// enum { NParams = n }; |
650 |
* @return true if the given rectangles intersect |
* @return true if the given rectangles intersect |
651 |
*/ |
*/ |
652 |
bool parallelRectIntersect(ZPt &p1, ZPt &p2, ZPt &p3, ZPt &p4) { |
bool parallelRectIntersect(ZPt &p1, ZPt &p2, ZPt &p3, ZPt &p4) { |
653 |
return (p2.x > p3.x) && (p4.x > p1.x) && (p2.y > p3.y) && (p4.y > p1.y); |
DBG(dbg_cull) << "called CullingCoordsys::parallellRectIntersect\n"; |
654 |
|
DBG(dbg_cull) << "(" << p1.x << "," << p1.y << "), (" << p2.x << "," << p2.y << ") <=> (" |
655 |
|
<< p3.x << "," << p3.y << "), (" << p4.x << "," << p4.y << ")\n"; |
656 |
|
|
657 |
|
return (p2.x > p3.x) && (p4.x > p1.x) && (p2.y > p3.y) && (p4.y > p1.y); |
658 |
} |
} |
659 |
/** Finds the bounding box of coordsys' unit square after |
/** Finds the bounding box of coordsys' unit square after |
660 |
* transformation. Assumes linear coordsys and transforms only |
* transformation. Assumes linear coordsys and transforms only |
664 |
* @param p2 "upper right corner" |
* @param p2 "upper right corner" |
665 |
*/ |
*/ |
666 |
void findBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) { |
void findBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) { |
667 |
|
DBG(dbg_cull) << "called CullingCoordsys::findBoundingBox\n"; |
668 |
int i, j; |
int i, j; |
669 |
float x1, y1, x2, y2; |
float x1, y1, x2, y2; |
670 |
for (i=0; i<=1; i++) { |
for (i=0; i<=1; i+=1) { |
671 |
for (j=0; j<=1; j++) { |
for (j=0; j<=1; j+=1) { |
672 |
if (i==0 && j==0) { |
if (i==0 && j==0) { |
673 |
/** Initializing. */ |
/** Initializing. */ |
674 |
ZPt tmpPt = cs->transform(ZPt(i, j, 0)); |
ZPt tmpPt = cs->transform(ZPt(i, j, 0)); |
695 |
* @param p2 "upper right corner" |
* @param p2 "upper right corner" |
696 |
*/ |
*/ |
697 |
void findDistortedBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) { |
void findDistortedBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) { |
698 |
double i; |
DBG(dbg_cull) << "called CullingCoordsys::findDistortedBoundingBox\n"; |
699 |
|
double i, step_x, step_y; |
700 |
float x1, y1, x2, y2; |
float x1, y1, x2, y2; |
701 |
|
int check_dist; |
702 |
|
|
703 |
/** Initializing. */ |
/** Initializing. */ |
704 |
|
check_dist = 30; // XXX |
705 |
|
|
706 |
ZPt o = cs->transform(ZPt(0, 0, 0)); |
ZPt o = cs->transform(ZPt(0, 0, 0)); |
707 |
x1 = o.x; y1 = o.y; |
ZPt u = cs->transform(ZPt(1, 1, 0)); |
708 |
x2 = o.x; y2 = o.y; |
|
709 |
|
if (fabs(o.x - u.x) / check_dist > 1) step_x = 1/(fabs(o.x - u.x) / check_dist); |
710 |
|
else step_x = 1; |
711 |
|
if (fabs(o.y - u.y) / check_dist > 1) step_y = 1/(fabs(o.y - u.y) / check_dist); |
712 |
|
else step_y = 1; |
713 |
|
DBG(dbg_cull) << "Step_X: " << step_x << " Step_Y: " << step_y << "\n"; |
714 |
|
|
715 |
|
x1 = u.x; y1 = u.y; |
716 |
|
x2 = u.x; y2 = u.y; |
717 |
|
|
718 |
/** Sweeps the unit square's vertices. */ |
/** Sweeps the unit square's vertices. */ |
719 |
/** Vertice (0,0) -> (1,0). */ |
/** Vertice (0,0) -> (1,0). */ |
720 |
for (i=0.1; i <= 1.0; i+=0.1) { |
for (i=0; i < 1.0; i+=step_x) { |
721 |
ZPt tmpPt = cs->transform(ZPt(i, 0, 0)); |
ZPt tmpPt = cs->transform(ZPt(i, 0, 0)); |
722 |
if (tmpPt.x < x1) x1 = tmpPt.x; |
if (tmpPt.x < x1) x1 = tmpPt.x; |
723 |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
726 |
} |
} |
727 |
|
|
728 |
/** Vertice (0,0) -> (0,1). */ |
/** Vertice (0,0) -> (0,1). */ |
729 |
for (i=0.1; i <= 1.0; i+=0.1) { |
for (i=step_y; i < 1.0; i+=step_y) { |
730 |
ZPt tmpPt = cs->transform(ZPt(0, i, 0)); |
ZPt tmpPt = cs->transform(ZPt(0, i, 0)); |
731 |
if (tmpPt.x < x1) x1 = tmpPt.x; |
if (tmpPt.x < x1) x1 = tmpPt.x; |
732 |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
735 |
} |
} |
736 |
|
|
737 |
/** Vertice (0,1) -> (1,1) */ |
/** Vertice (0,1) -> (1,1) */ |
738 |
for (i=0.1; i >= 1.0; i+=0.1) { |
for (i=0; i < 1.0; i+=step_x) { |
739 |
ZPt tmpPt = cs->transform(ZPt(i, 1, 0)); |
ZPt tmpPt = cs->transform(ZPt(i, 1, 0)); |
740 |
if (tmpPt.x < x1) x1 = tmpPt.x; |
if (tmpPt.x < x1) x1 = tmpPt.x; |
741 |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
744 |
} |
} |
745 |
|
|
746 |
/** Vertice (1,0) -> (1,1) */ |
/** Vertice (1,0) -> (1,1) */ |
747 |
for (i=0.1; i < 1.0; i+=0.1) { |
for (i=0; i < 1.0; i+=step_y) { |
748 |
ZPt tmpPt = cs->transform(ZPt(1, i, 0)); |
ZPt tmpPt = cs->transform(ZPt(1, i, 0)); |
749 |
if (tmpPt.x < x1) x1 = tmpPt.x; |
if (tmpPt.x < x1) x1 = tmpPt.x; |
750 |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
760 |
CullingCoordSys(CoordSys *parent, CoordSys *clip) |
CullingCoordSys(CoordSys *parent, CoordSys *clip) |
761 |
: CoordSys(parent), clipSuper(clip) { } |
: CoordSys(parent), clipSuper(clip) { } |
762 |
virtual void setSuper(CoordSys **super) { |
virtual void setSuper(CoordSys **super) { |
763 |
|
DBG(dbg_cull) << "called CullingCoordsys::setSuper\n"; |
764 |
CoordSys::setSuper(super); |
CoordSys::setSuper(super); |
765 |
this->clipSuper = super[1]; |
this->clipSuper = super[1]; |
766 |
} |
} |
767 |
enum { NParams = 0, NPrevious = 2, NParents = 2 }; |
enum { NParams = 0, NPrevious = 2, NParents = 2 }; |
768 |
virtual void setParams(float *params) { } |
virtual void setParams(float *params) { } |
769 |
virtual CoordSys *createInverse() { |
virtual CoordSys *createInverse() { |
770 |
return new ConcatCoordSys(super->getInverse(), clipSuper->getInverse()); |
DBG(dbg_cull) << "called CullingCoordsys::createInverse\n"; |
771 |
|
return super->getInverse(); |
772 |
} |
} |
773 |
virtual void vertex(const ZPt &p) const { |
virtual void vertex(const ZPt &p) const { |
774 |
|
DBG(dbg_cull) << "called CullingCoordsys::vertex\n"; |
775 |
super->vertex(p); |
super->vertex(p); |
|
clipSuper->vertex(p); |
|
776 |
} |
} |
777 |
virtual ZPt transform(const ZPt &p) const { |
virtual ZPt transform(const ZPt &p) const { |
778 |
return super->transform(p); |
DBG(dbg_cull) << "called CullingCoordsys::transform\n"; |
779 |
|
return super->transform(p); |
780 |
} |
} |
781 |
virtual float nonlinearity(const ZPt &p, float radius) { |
virtual float nonlinearity(const ZPt &p, float radius) { |
782 |
|
DBG(dbg_cull) << "called CullingCoordsys::nonlinearity\n"; |
783 |
float n1 = super->nonlinearity(p, radius); |
float n1 = super->nonlinearity(p, radius); |
784 |
float n2 = clipSuper->nonlinearity(super->transform(p), radius); |
float n2 = clipSuper->nonlinearity(super->transform(p), radius); |
785 |
return (n1 > n2 ? n1 : n2); |
return (n1 > n2 ? n1 : n2); |
786 |
} |
} |
787 |
virtual bool canPerformGL() { |
virtual bool canPerformGL() { |
788 |
return super->canPerformGL() && clipSuper->canPerformGL(); |
DBG(dbg_cull) << "called CullingCoordsys::canPerformGL\n"; |
789 |
|
return super->canPerformGL(); |
790 |
} |
} |
791 |
virtual bool performGL() { |
virtual bool performGL() { |
792 |
if(!super->performGL()) return false; |
DBG(dbg_cull) << "called CullingCoordsys::performGL\n"; |
793 |
return clipSuper->performGL(); |
return super->performGL(); |
794 |
} |
} |
795 |
/** Cullin coordsys' shouldBeDrawn() returns false if and only if |
/** Cullin coordsys' shouldBeDrawn() returns false if and only if |
796 |
* it's sure that its parents' unit squares do not intersect. |
* it's sure that its parents' unit squares do not intersect. |
797 |
*/ |
*/ |
798 |
virtual bool shouldBeDrawn() { |
virtual bool shouldBeDrawn() { |
799 |
|
DBG(dbg_cull) << "called CullingCoordsys::shouldBeDrawn\n"; |
800 |
/** Lower left and upper right points of bounding boxes for |
/** Lower left and upper right points of bounding boxes for |
801 |
* parents' unit squares (after transformation). |
* parents' unit squares (after transformation). |
802 |
*/ |
*/ |
803 |
ZPt p1, p2, p3, p4; |
ZPt p1, p2, p3, p4; |
804 |
|
|
805 |
if (super->nonlinearity(ZPt(0.5, 0.5, 0), 1/sqrt(2)) != 0) |
if (super->nonlinearity(ZPt(0.5, 0.5, 0), 1/sqrt(2)) != 0) |
806 |
findDistortedBoundingBox(super, p1, p2); |
findDistortedBoundingBox(super, p1, p2); |
807 |
else findBoundingBox(super, p1, p2); |
else findBoundingBox(super, p1, p2); |
808 |
|
|
809 |
if (clipSuper->nonlinearity(ZPt(0.5, 0.5, 0), 1/sqrt(2)) != 0) |
if (clipSuper->nonlinearity(ZPt(0.5, 0.5, 0), 1/sqrt(2)) != 0) |
810 |
findDistortedBoundingBox(clipSuper, p3, p4); |
findDistortedBoundingBox(clipSuper, p3, p4); |
811 |
else findDistortedBoundingBox(clipSuper, p3, p4); |
else findBoundingBox(clipSuper, p3, p4); |
812 |
|
|
813 |
return (parallelRectIntersect(p1, p2, p3, p4)); |
return (parallelRectIntersect(p1, p2, p3, p4)); |
814 |
} |
} |
848 |
extern SomeFactory* facs[]; |
extern SomeFactory* facs[]; |
849 |
|
|
850 |
|
|
851 |
/* This mustn't change without changing GLVobCoorder2 as well. |
/** Factories for different coordsys types. |
852 |
|
* These factories are currently used form CoordSet::create and |
853 |
|
* they return a pointer to new coordsys created with "new". |
854 |
|
* Array facs[] mustn't change without changing GLVobCoorder as well. |
855 |
*/ |
*/ |
856 |
SomeFactory* facs[] = { |
SomeFactory* facs[] = { |
857 |
0, |
0, |
865 |
new DerTransFactory<BuoyOnCircleCoords>(), // 7 |
new DerTransFactory<BuoyOnCircleCoords>(), // 7 |
866 |
new NoTransFactory<ConcatCoordSys>(), // 8 |
new NoTransFactory<ConcatCoordSys>(), // 8 |
867 |
new DerTransFactory<NadirOriginCoords>(), // 9 |
new DerTransFactory<NadirOriginCoords>(), // 9 |
868 |
|
new NoTransFactory<CullingCoordSys>(), // 10 |
869 |
0 |
0 |
870 |
}; |
}; |
871 |
|
|
1028 |
} |
} |
1029 |
DBG(dbg) << "CS assigned "<<tp<<"\n"; |
DBG(dbg) << "CS assigned "<<tp<<"\n"; |
1030 |
|
|
1031 |
|
/** Finally, creates a new coordsys of demanded type and sets its parents and |
1032 |
|
* params. If the initialized coordsys (according to its initialized attributes) |
1033 |
|
* decides not to be drawn, it will be deleted and replaced with the NULL pointer. |
1034 |
|
*/ |
1035 |
CoordSys *c = create(tp); |
CoordSys *c = create(tp); |
1036 |
cs[i] = c; |
cs[i] = c; |
1037 |
c->setSuper(prev); |
c->setSuper(prev); |
1038 |
c->setParams(&(params[0]) + parind); |
c->setParams(&(params[0]) + parind); |
1039 |
|
if (!cs[i]->shouldBeDrawn()) { |
1040 |
|
DBG(dbg) << "CS should not be drawn... freeing it with delete.\n"; |
1041 |
|
delete cs[i]; // Must be deleted, because created with "new" in factories. |
1042 |
|
cs[i] = NULL; |
1043 |
|
} |
1044 |
} |
} |
1045 |
nextInd:; |
nextInd:; |
1046 |
} |
} |