00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009 #include "vgui_draw_line.h"
00010 #include <vgui/vgui_gl.h>
00011 #include <vgui/internals/vgui_multiply_4x4.h>
00012 #include <vgui/internals/vgui_transpose_4x4.h>
00013
00014
00015
00016 #define dot4(a, b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3])
00017 #define l_c4(a, x, b, y, ax_plus_by) { for (int i=0; i<4; ++i) (ax_plus_by)[i] = (a)*(x)[i] + (b)*(y)[i]; }
00018
00019 bool vgui_draw_line(double const T[4][4], double const X[4], double const Y[4])
00020 {
00021 double T0_X = dot4(T[0], X);
00022 double T1_X = dot4(T[1], X);
00023 double T3_X = dot4(T[3], X);
00024
00025 double T0_Y = dot4(T[0], Y);
00026 double T1_Y = dot4(T[1], Y);
00027 double T3_Y = dot4(T[3], Y);
00028
00029 double tmp[4];
00030 glBegin(GL_LINE_STRIP);
00031
00032
00033 {
00034 double u = T0_X+T3_X;
00035 double v = T0_Y+T3_Y;
00036 double y_dev = (v*T1_X - u*T1_Y);
00037 double w_dev = (v*T3_X - u*T3_Y);
00038 if (!w_dev) { }
00039 else if ((w_dev>0) ? (-w_dev<=y_dev && y_dev<=w_dev) : (-w_dev>=y_dev && y_dev>=w_dev)) {
00040 l_c4(v, X, -u, Y, tmp);
00041 glVertex4dv(tmp);
00042 }
00043 }
00044
00045
00046 {
00047 double u = T0_X-T3_X;
00048 double v = T0_Y-T3_Y;
00049 double y_dev = (v*T1_X - u*T1_Y);
00050 double w_dev = (v*T3_X - u*T3_Y);
00051 if (!w_dev) { }
00052 else if ((w_dev>0) ? (-w_dev<=y_dev && y_dev<=w_dev) : (-w_dev>=y_dev && y_dev>=w_dev)) {
00053 l_c4(v, X, -u, Y, tmp);
00054 glVertex4dv(tmp);
00055 }
00056 }
00057
00058
00059 {
00060 double u = T1_X+T3_X;
00061 double v = T1_Y+T3_Y;
00062 double x_dev = (v*T0_X - u*T0_Y);
00063 double w_dev = (v*T3_X - u*T3_Y);
00064 if (!w_dev) { }
00065 else if ((w_dev>0) ? (-w_dev<=x_dev && x_dev<=w_dev) : (-w_dev>=x_dev && x_dev>=w_dev)) {
00066 l_c4(v, X, -u, Y, tmp);
00067 glVertex4dv(tmp);
00068 }
00069 }
00070
00071
00072 {
00073 double u = T1_X-T3_X;
00074 double v = T1_Y-T3_Y;
00075 double x_dev = (v*T0_X - u*T0_Y);
00076 double w_dev = (v*T3_X - u*T3_Y);
00077 if (!w_dev) { }
00078 else if ((w_dev>0) ? (-w_dev<=x_dev && x_dev<=w_dev) : (-w_dev>=x_dev && x_dev>=w_dev)) {
00079 l_c4(v, X, -u, Y, tmp);
00080 glVertex4dv(tmp);
00081 }
00082 }
00083
00084 glEnd();
00085 return true;
00086 }
00087
00088 bool vgui_draw_line(double const P[4][4], double const M[4][4], double const X[4], double const Y[4])
00089 {
00090 double T[4][4];
00091 vgui_multiply_4x4(P, M, T);
00092 return vgui_draw_line(T, X, Y);
00093 }
00094
00095 bool vgui_draw_line(double const X[4], double const Y[4])
00096 {
00097 double P[4][4]; glGetDoublev(GL_PROJECTION_MATRIX, &P[0][0]); vgui_transpose_4x4(P);
00098 double M[4][4]; glGetDoublev(GL_MODELVIEW_MATRIX, &M[0][0]); vgui_transpose_4x4(M);
00099
00100 double T[4][4];
00101 vgui_multiply_4x4(P, M, T);
00102 return vgui_draw_line(T, X, Y);
00103 }
00104
00105
00106
00107 #define dot3(a, b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2])
00108 #define cross3(a, b, c) { \
00109 (c)[0] = (a)[1]*(b)[2] - (a)[2]*(b)[1]; \
00110 (c)[1] = (a)[2]*(b)[0] - (a)[0]*(b)[2]; \
00111 (c)[2] = (a)[0]*(b)[1] - (a)[1]*(b)[0]; \
00112 }
00113 #define add3(a, b, c) { for (int i=0; i<3; ++i) (c)[i] = (a)[i] + (b)[i]; }
00114 #define sub3(a, b, c) { for (int i=0; i<3; ++i) (c)[i] = (a)[i] - (b)[i]; }
00115 #define trace(str)
00116
00117 bool vgui_draw_line(double const T[4][4], double a, double b, double c)
00118 {
00119 double l[3] = { a, b, c };
00120
00121 double M[3][3] = {
00122 { T[0][0], T[0][1], T[0][3] },
00123 { T[1][0], T[1][1], T[1][3] },
00124 { T[3][0], T[3][1], T[3][3] }
00125 };
00126
00127 double M0_l[3]; cross3(M[0], l, M0_l);
00128 double M1_l[3]; cross3(M[1], l, M1_l);
00129 double M2_l[3]; cross3(M[2], l, M2_l);
00130
00131 double tmp[3];
00132 glBegin(GL_LINE_STRIP);
00133
00134
00135 {
00136 add3(M0_l, M2_l, tmp);
00137 double y_dev = dot3(M[1], tmp);
00138 double w_dev = dot3(M[2], tmp);
00139 if (w_dev>0) {
00140 if (-w_dev<=y_dev && y_dev<=w_dev) {
00141 trace("x=-1"); glVertex4d( tmp[0], tmp[1], 0, tmp[2]); }
00142 }
00143 else if (w_dev<0) {
00144 if (-w_dev>=y_dev && y_dev>=w_dev) {
00145 trace("x=-1"); glVertex4d(-tmp[0], -tmp[1], 0, -tmp[2]); }
00146 }
00147 }
00148
00149
00150 {
00151 sub3(M0_l, M2_l, tmp);
00152 double y_dev = dot3(M[1], tmp);
00153 double w_dev = dot3(M[2], tmp);
00154 if (w_dev>0) {
00155 if (-w_dev<=y_dev && y_dev<=w_dev) {
00156 trace("x=+1"); glVertex4d( tmp[0], tmp[1], 0, tmp[2]); }
00157 }
00158 else if (w_dev<0) {
00159 if (-w_dev>=y_dev && y_dev>=w_dev) {
00160 trace("x=+1"); glVertex4d(-tmp[0], -tmp[1], 0, -tmp[2]); }
00161 }
00162 }
00163
00164
00165 {
00166 add3(M1_l, M2_l, tmp);
00167 double x_dev = dot3(M[0], tmp);
00168 double w_dev = dot3(M[2], tmp);
00169 if (w_dev>0) {
00170 if (-w_dev<=x_dev && x_dev<=w_dev) {
00171 trace("y=-1"); glVertex4d( tmp[0], tmp[1], 0, tmp[2]); }
00172 }
00173 else if (w_dev<0) {
00174 if (-w_dev>=x_dev && x_dev>=w_dev) {
00175 trace("y=-1"); glVertex4d(-tmp[0], -tmp[1], 0, -tmp[2]); }
00176 }
00177 }
00178
00179
00180 {
00181 sub3(M1_l, M2_l, tmp);
00182 double x_dev = dot3(M[0], tmp);
00183 double w_dev = dot3(M[2], tmp);
00184 if (w_dev>0) {
00185 if (-w_dev<=x_dev && x_dev<=w_dev) {
00186 trace("y=+1"); glVertex4d( tmp[0], tmp[1], 0, tmp[2]); }
00187 }
00188 else if (w_dev<0) {
00189 if (-w_dev>=x_dev && x_dev>=w_dev) {
00190 trace("y=+1"); glVertex4d(-tmp[0], -tmp[1], 0, -tmp[2]); }
00191 }
00192 }
00193
00194 trace("");
00195 glEnd();
00196
00197 return true;
00198 }
00199
00200 bool vgui_draw_line(double const P[4][4], double const M[4][4], double a, double b, double c)
00201 {
00202 double T[4][4];
00203 vgui_multiply_4x4(P, M, T);
00204 return vgui_draw_line(T, a, b, c);
00205 }
00206
00207 bool vgui_draw_line(double a, double b, double c)
00208 {
00209 double P[4][4]; glGetDoublev(GL_PROJECTION_MATRIX, &P[0][0]); vgui_transpose_4x4(P);
00210 double M[4][4]; glGetDoublev(GL_MODELVIEW_MATRIX, &M[0][0]); vgui_transpose_4x4(M);
00211 double T[4][4]; vgui_multiply_4x4(P, M, T);
00212 return vgui_draw_line(T, a, b, c);
00213 }