2 |
#include "libfisheye/Fisheye.hxx" |
#include "libfisheye/Fisheye.hxx" |
3 |
#include "Coords.hxx" |
#include "Coords.hxx" |
4 |
#include <GL/gl.h> |
#include <GL/gl.h> |
5 |
|
#include <math.h> |
6 |
|
|
7 |
namespace Coords { |
namespace Coords { |
8 |
DBGVAR(dbg, "Coords.general"); |
DBGVAR(dbg, "Coords.general"); |
833 |
|
|
834 |
|
|
835 |
/** Culling coordsys can decide not to be drawn when its |
/** Culling coordsys can decide not to be drawn when its |
836 |
* parents' unit squares do not intersect. |
* parents' boxes do not intersect. |
837 |
*/ |
*/ |
838 |
class CullingCoordSys : public CoordSys { |
class CullingCoordSys : public CoordSys { |
839 |
CoordSys *testSuper; |
CoordSys *testSuper; |
855 |
DBG(dbg_cull) << "(" << p1.x << "," << p1.y << "), (" << p2.x << "," << p2.y << ") <=> (" |
DBG(dbg_cull) << "(" << p1.x << "," << p1.y << "), (" << p2.x << "," << p2.y << ") <=> (" |
856 |
<< p3.x << "," << p3.y << "), (" << p4.x << "," << p4.y << ")\n"; |
<< p3.x << "," << p3.y << "), (" << p4.x << "," << p4.y << ")\n"; |
857 |
|
|
858 |
|
|
859 |
|
/* |
860 |
glLineWidth(1); |
glLineWidth(1); |
861 |
glColor3f(1, 1, 1); |
glColor3f(1, 1, 1); |
862 |
glDisable(GL_TEXTURE_2D); |
glDisable(GL_TEXTURE_2D); |
872 |
glVertex3f(p3.x, p4.y,0); |
glVertex3f(p3.x, p4.y,0); |
873 |
glVertex3f(p4.x, p4.y,0); |
glVertex3f(p4.x, p4.y,0); |
874 |
glVertex3f(p4.x, p3.y,0); |
glVertex3f(p4.x, p3.y,0); |
875 |
glEnd(); |
glEnd(); |
876 |
|
*/ |
877 |
|
|
878 |
return (p2.x > p3.x) && (p4.x > p1.x) && (p2.y > p3.y) && (p4.y > p1.y); |
return (p2.x > p3.x) && (p4.x > p1.x) && (p2.y > p3.y) && (p4.y > p1.y); |
879 |
} |
} |
880 |
/** Finds the bounding box of coordsys' unit square after |
/** Finds the bounding box of coordsys' box after |
881 |
* transformation. Assumes linear coordsys and transforms only |
* transformation. Assumes linear coordsys and transforms only |
882 |
* corner's of the unit square. |
* corner's of the box. |
883 |
* @param cs coordinate system for the unit square |
* @param cs the coordinate system, which box to use |
884 |
* @param p1 "lower left corner" |
* @param p1 "lower left corner" |
885 |
* @param p2 "upper right corner" |
* @param p2 "upper right corner" |
886 |
*/ |
*/ |
887 |
void findBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) { |
void findBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) { |
888 |
DBG(dbg_cull) << "called CullingCoordsys::findBoundingBox\n"; |
DBG(dbg_cull) << "called CullingCoordsys::findBoundingBox\n"; |
889 |
int i, j; |
float i, j; |
890 |
|
Pt box = cs->getSqSize(); |
891 |
float x1, y1, x2, y2; |
float x1, y1, x2, y2; |
892 |
for (i=0; i<=1; i+=1) { |
for (i=0; i<=box.x; i+=box.y) { |
893 |
for (j=0; j<=1; j+=1) { |
for (j=0; j<=box.y; j+=box.y) { |
894 |
if (i==0 && j==0) { |
if (i==0 && j==0) { |
895 |
/** Initializing. */ |
/** Initializing. */ |
896 |
ZPt tmpPt = cs->transform(ZPt(i, j, 0)); |
ZPt tmpPt = cs->transform(ZPt(i, j, 0)); |
909 |
p1 = ZPt(x1, y1, 0); |
p1 = ZPt(x1, y1, 0); |
910 |
p2 = ZPt(x2, y2, 0); |
p2 = ZPt(x2, y2, 0); |
911 |
} |
} |
912 |
/** Finds the bounding box of coordsys' unit square after |
/** Finds the bounding box of coordsys' box after |
913 |
* transformation. Because the coordsys may be distorted, |
* transformation. Because the coordsys may be distorted, |
914 |
* searches bounfing box's coners also within vertices. |
* searches bounding box's coners also along vertices. |
915 |
* @param cs coordinate system for the unit square |
* @param cs the coordinate system, which box to use |
916 |
* @param p1 "lower left corner" |
* @param p1 "lower left corner" |
917 |
* @param p2 "upper right corner" |
* @param p2 "upper right corner" |
918 |
*/ |
*/ |
919 |
void findDistortedBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) { |
void findDistortedBoundingBox(CoordSys *cs, ZPt &p1, ZPt &p2) { |
920 |
DBG(dbg_cull) << "called CullingCoordsys::findDistortedBoundingBox\n"; |
DBG(dbg_cull) << "called CullingCoordsys::findDistortedBoundingBox\n"; |
921 |
double i, step_x, step_y; |
double i, step_x, step_y; |
922 |
|
Pt box = cs->getSqSize(); |
923 |
float x1, y1, x2, y2; |
float x1, y1, x2, y2; |
924 |
int check_dist; |
int check_dist; |
925 |
|
|
927 |
check_dist = 100; // XXX Adjusts the scanning frequency. |
check_dist = 100; // XXX Adjusts the scanning frequency. |
928 |
|
|
929 |
ZPt o = cs->transform(ZPt(0, 0, 0)); |
ZPt o = cs->transform(ZPt(0, 0, 0)); |
930 |
ZPt u = cs->transform(ZPt(1, 1, 0)); |
ZPt u = cs->transform(ZPt(box.x, box.y, 0)); |
931 |
|
|
932 |
if (fabs(o.x - u.x) / check_dist > 1) step_x = 1/(fabs(o.x - u.x) / check_dist); |
if (fabs(o.x - u.x) / check_dist > box.x) |
933 |
else step_x = 1; |
step_x = box.x/(fabs(o.x - u.x) / check_dist); |
934 |
if (fabs(o.y - u.y) / check_dist > 1) step_y = 1/(fabs(o.y - u.y) / check_dist); |
else step_x = box.x; |
935 |
else step_y = 1; |
if (fabs(o.y - u.y) / check_dist > box.y) |
936 |
|
step_y = box.y/(fabs(o.y - u.y) / check_dist); |
937 |
|
else step_y = box.y; |
938 |
DBG(dbg_cull) << "Step_X: " << step_x << " Step_Y: " << step_y << "\n"; |
DBG(dbg_cull) << "Step_X: " << step_x << " Step_Y: " << step_y << "\n"; |
939 |
|
|
940 |
x1 = u.x; y1 = u.y; |
x1 = u.x; y1 = u.y; |
941 |
x2 = u.x; y2 = u.y; |
x2 = u.x; y2 = u.y; |
942 |
|
|
943 |
/** Sweeps the unit square's vertices. */ |
/** Sweeps the box's vertices. */ |
944 |
/** Vertice (0,0) -> (1,0). */ |
/** Vertice (0,0) -> (w,0). */ |
945 |
for (i=0; i < 1.0; i+=step_x) { |
for (i=0; i < box.x; i+=step_x) { |
946 |
ZPt tmpPt = cs->transform(ZPt(i, 0, 0)); |
ZPt tmpPt = cs->transform(ZPt(i, 0, 0)); |
947 |
if (tmpPt.x < x1) x1 = tmpPt.x; |
if (tmpPt.x < x1) x1 = tmpPt.x; |
948 |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
950 |
else if (tmpPt.y > y2) y2 = tmpPt.y; |
else if (tmpPt.y > y2) y2 = tmpPt.y; |
951 |
} |
} |
952 |
|
|
953 |
/** Vertice (0,0) -> (0,1). */ |
/** Vertice (0,0) -> (0,h). */ |
954 |
for (i=step_y; i < 1.0; i+=step_y) { |
for (i=step_y; i < box.y; i+=step_y) { |
955 |
ZPt tmpPt = cs->transform(ZPt(0, i, 0)); |
ZPt tmpPt = cs->transform(ZPt(0, i, 0)); |
956 |
if (tmpPt.x < x1) x1 = tmpPt.x; |
if (tmpPt.x < x1) x1 = tmpPt.x; |
957 |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
959 |
else if (tmpPt.y > y2) y2 = tmpPt.y; |
else if (tmpPt.y > y2) y2 = tmpPt.y; |
960 |
} |
} |
961 |
|
|
962 |
/** Vertice (0,1) -> (1,1) */ |
/** Vertice (0,h) -> (w,h) */ |
963 |
for (i=0; i < 1.0; i+=step_x) { |
for (i=0; i < box.x; i+=step_x) { |
964 |
ZPt tmpPt = cs->transform(ZPt(i, 1, 0)); |
ZPt tmpPt = cs->transform(ZPt(i, box.y, 0)); |
965 |
if (tmpPt.x < x1) x1 = tmpPt.x; |
if (tmpPt.x < x1) x1 = tmpPt.x; |
966 |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
967 |
if (tmpPt.y < y1) y1 = tmpPt.y; |
if (tmpPt.y < y1) y1 = tmpPt.y; |
968 |
else if (tmpPt.y > y2) y2 = tmpPt.y; |
else if (tmpPt.y > y2) y2 = tmpPt.y; |
969 |
} |
} |
970 |
|
|
971 |
/** Vertice (1,0) -> (1,1) */ |
/** Vertice (w,0) -> (w,h) */ |
972 |
for (i=0; i < 1.0; i+=step_y) { |
for (i=0; i < box.y; i+=step_y) { |
973 |
ZPt tmpPt = cs->transform(ZPt(1, i, 0)); |
ZPt tmpPt = cs->transform(ZPt(box.x, i, 0)); |
974 |
if (tmpPt.x < x1) x1 = tmpPt.x; |
if (tmpPt.x < x1) x1 = tmpPt.x; |
975 |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
else if (tmpPt.x > x2) x2 = tmpPt.x; |
976 |
if (tmpPt.y < y1) y1 = tmpPt.y; |
if (tmpPt.y < y1) y1 = tmpPt.y; |
1018 |
DBG(dbg_cull) << "called CullingCoordsys::performGL\n"; |
DBG(dbg_cull) << "called CullingCoordsys::performGL\n"; |
1019 |
return super->performGL(); |
return super->performGL(); |
1020 |
} |
} |
1021 |
/** Cullin coordsys' shouldBeDrawn() returns false if and only if |
/** CullingCoordSys' shouldBeDrawn() returns true always when boxes |
1022 |
* it's sure that its parents' unit squares do not intersect. |
* of its test and clip coordinate systems do intersect. When |
1023 |
|
* the boxes don't intersect, it should retun false. |
1024 |
*/ |
*/ |
1025 |
virtual bool shouldBeDrawn() { |
virtual bool shouldBeDrawn() { |
1026 |
DBG(dbg_cull) << "called CullingCoordsys::shouldBeDrawn\n"; |
DBG(dbg_cull) << "called CullingCoordsys::shouldBeDrawn\n"; |
1027 |
|
Pt box; |
1028 |
|
float hyp; |
1029 |
/** Lower left and upper right points of bounding boxes for |
/** Lower left and upper right points of bounding boxes for |
1030 |
* parents' unit squares (after transformation). |
* parents' box (after transformation). |
1031 |
*/ |
*/ |
1032 |
ZPt p1, p2, p3, p4; |
ZPt p1, p2, p3, p4; |
1033 |
|
|
1034 |
if (testSuper->nonlinearity(ZPt(0.5, 0.5, 0), 1/sqrt(2)) != 0) |
box = testSuper->getSqSize(); |
1035 |
|
hyp = hypot(box.x/2, box.y/2); |
1036 |
|
if (testSuper->nonlinearity(ZPt(box.x/2, box.y/2, 0), hyp) > 1/hyp) |
1037 |
findDistortedBoundingBox(testSuper, p1, p2); |
findDistortedBoundingBox(testSuper, p1, p2); |
1038 |
else findBoundingBox(testSuper, p1, p2); |
else findBoundingBox(testSuper, p1, p2); |
1039 |
|
|
1040 |
if (clipSuper->nonlinearity(ZPt(0.5, 0.5, 0), 1/sqrt(2)) != 0) |
box = clipSuper->getSqSize(); |
1041 |
|
hyp = hypot(box.x/2, box.y/2); |
1042 |
|
if (clipSuper->nonlinearity(ZPt(box.x/2, box.y/2, 0), hyp) > 1/hyp) |
1043 |
findDistortedBoundingBox(clipSuper, p3, p4); |
findDistortedBoundingBox(clipSuper, p3, p4); |
1044 |
else findBoundingBox(clipSuper, p3, p4); |
else findBoundingBox(clipSuper, p3, p4); |
1045 |
|
|