You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
645 lines
16 KiB
645 lines
16 KiB
/* map3d.c */ |
|
|
|
#include <stdio.h> |
|
#include <math.h> |
|
#include <strings.h> |
|
#include <fcntl.h> |
|
#include <unistd.h> |
|
|
|
#include "vm.h" |
|
|
|
#define NLIGHTS 16 |
|
|
|
#define PANMAX 127 |
|
#define PANRANGE M_PI_2 |
|
#define PANOFFSET 128 |
|
#define TILTMAX 127 |
|
#define TILTRANGE M_PI_4 |
|
#define TILTOFFSET 128 |
|
|
|
#define MAP3D_FILENAME ".map3d.caldata" |
|
|
|
struct light { |
|
double M[4][3]; |
|
double cp[3][3]; |
|
double pan[3]; |
|
double tilt[3]; |
|
}; |
|
|
|
struct light map3d_cal[NLIGHTS]; |
|
|
|
#define MAG(x) (sqrt(SQUARE(x[0]) + SQUARE(x[1]) + SQUARE(x[2]))) |
|
#define SQUARE(x) ((x) * (x)) |
|
#define PYTHAG3(a, b) sqrt(SQUARE(a[0]-b[0]) + SQUARE(a[1]-b[1]) + SQUARE(a[2]-b[2])) |
|
|
|
#define DEG(x) (180 * (x) / M_PI) |
|
|
|
void normalise(double *v) |
|
{ |
|
double mag; |
|
int i; |
|
|
|
mag = MAG(v); |
|
|
|
for (i = 0; i < 3; i++) |
|
v[i] /= mag; |
|
} |
|
|
|
#define MM map3d_cal[light].M |
|
|
|
void multiply(int light, double *i, double *o) { |
|
o[0] = i[0] * MM[0][0] + i[1] * MM[1][0] + i[2] * MM[2][0] + MM[3][0]; |
|
o[1] = i[0] * MM[0][1] + i[1] * MM[1][1] + i[2] * MM[2][1] + MM[3][1]; |
|
o[2] = i[0] * MM[0][2] + i[1] * MM[1][2] + i[2] * MM[2][2] + MM[3][2]; |
|
} |
|
|
|
#undef MM |
|
|
|
void map3d_init(void) |
|
{ |
|
} |
|
|
|
void map3d_close(void) |
|
{ |
|
} |
|
|
|
void map3d_save(void) |
|
{ |
|
int fd, rv; |
|
|
|
fd = open(MAP3D_FILENAME, O_WRONLY | O_CREAT, 0666); |
|
rv = write(fd, map3d_cal, sizeof(map3d_cal)); |
|
if (rv != sizeof(map3d_cal)) |
|
printf("Warning: Calibration data not saved correctly\n"); |
|
close(fd); |
|
} |
|
|
|
int map3d_load(void) |
|
{ |
|
int fd, rv; |
|
|
|
fd = open(MAP3D_FILENAME, O_RDONLY, 0666); |
|
if (!fd) |
|
return 0; |
|
rv = read(fd, map3d_cal, sizeof(map3d_cal)); |
|
if (rv != sizeof(map3d_cal)) |
|
printf("Warning: Calibration data not read correctly\n"); |
|
close(fd); |
|
return 1; |
|
} |
|
|
|
void map3d_transform(int light, double x, double y, double z, |
|
int *pan, int *tilt) |
|
{ |
|
double pv[3]; |
|
double rv[3]; |
|
double p, t; |
|
|
|
// printf("Transforming for light %d: (%f, %f, %f)\n", light, x, y, z); |
|
fflush(stdout); |
|
pv[0] = x; |
|
pv[1] = y; |
|
pv[2] = z; |
|
multiply(light, pv, rv); |
|
normalise(rv); |
|
t = asin(rv[1]); |
|
p = asin(rv[0]/cos(t)); |
|
|
|
*pan = (int)round((p * PANMAX)/PANRANGE) + PANOFFSET; |
|
*tilt = (int)round((t * TILTMAX)/TILTRANGE) + TILTOFFSET; |
|
if (*pan < 0) |
|
*pan = 0; |
|
if (*pan > 255) |
|
*pan = 255; |
|
if (*tilt < 0) |
|
*tilt = 0; |
|
if (*tilt > 255) |
|
*tilt = 255; |
|
// printf("pan = %d, tilt = %d\n", *pan, *tilt); |
|
} |
|
|
|
void map3d_setcal(int light, int n, double x, double y, double z, |
|
int pan, int tilt) |
|
{ |
|
printf("setcal(%d, %d, %f, %f, %f, %d, %d)\n", light, n, x, y, z, pan, tilt); |
|
map3d_cal[light].cp[n][0] = x; |
|
map3d_cal[light].cp[n][1] = y; |
|
map3d_cal[light].cp[n][2] = z; |
|
map3d_cal[light].pan[n] = PANRANGE * ((double)pan - PANOFFSET) / PANMAX; |
|
map3d_cal[light].tilt[n] = TILTRANGE * ((double)tilt - TILTOFFSET) |
|
/ TILTMAX; |
|
printf("Setcal: pan = %f, tilt = %f\n", map3d_cal[light].pan[n], map3d_cal[light].tilt[n]); |
|
} |
|
|
|
void unitvector(double *vec, double pan, double tilt) |
|
{ |
|
double tmp[3]; |
|
double cosp, sinp, cost, sint; |
|
|
|
/* Precalculate some values */ |
|
cosp = cos(pan); |
|
sinp = sin(pan); |
|
cost = cos(tilt); |
|
sint = sin(tilt); |
|
|
|
/* Start with a unit vector */ |
|
vec[0] = 0; |
|
vec[1] = 0; |
|
vec[2] = 1; |
|
|
|
/* Rotate around X axis (tilt) */ |
|
tmp[0] = vec[0]; |
|
tmp[1] = vec[1]*cost + vec[2]*sint; |
|
tmp[2] = vec[2]*cost - vec[1]*sint; |
|
|
|
/* Rotate around Y axis (pan) */ |
|
vec[0] = tmp[0]*cosp + tmp[2]*sinp; |
|
vec[1] = tmp[1]; |
|
vec[2] = tmp[2]*cosp - tmp[0]*sinp; |
|
} |
|
|
|
double dotproduct(double *a, double *b) |
|
{ |
|
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; |
|
} |
|
|
|
void crossproduct(double *a, double *b, double *r) |
|
{ |
|
r[0] = a[1]*b[2] - a[2]*b[1]; |
|
r[1] = a[2]*b[0] - a[0]*b[2]; |
|
r[2] = a[0]*b[1] - a[1]*b[0]; |
|
} |
|
|
|
void dumpmatrix(double sim[12][13]) { |
|
int i, j; |
|
|
|
for (i = 0; i < 12; i++) { |
|
for (j = 0; j < 13; j++) |
|
printf("\t%f", sim[i][j]); |
|
printf("\n"); |
|
} |
|
printf("\n"); |
|
} |
|
|
|
void eliminate(double sim[12][13], double *var) |
|
{ |
|
int i, j, k, maxpos; |
|
double max, val, tmp, x; |
|
|
|
dumpmatrix(sim); |
|
|
|
for (i = 0; i < 12; i++) { |
|
/* Find the maximum element in the ith column */ |
|
max = 0.0; |
|
maxpos = i; |
|
for (j = i; j < 12; j++) { |
|
val = fabs(sim[j][i]); |
|
if (val > max) { |
|
max = val; |
|
maxpos = j; |
|
} |
|
} |
|
if (maxpos != i) |
|
for (j = 0; j < 13; j++) { |
|
tmp = sim[maxpos][j]; |
|
sim[maxpos][j] = sim[i][j]; |
|
sim[i][j] = tmp; |
|
} |
|
if (fabs(sim[i][i]) < 0.0001) |
|
printf("Warning: Lost accuracy at row %d\n", i); |
|
for (j = i+1; j < 12; j++) { |
|
if (fabs(sim[j][i]) > 0.0) { |
|
/* |
|
* Subtract x times row i from row j, |
|
* where x is chosen such that |
|
* sim[i][i] * x = sim[j][i] |
|
*/ |
|
x = sim[j][i] / sim[i][i]; |
|
for (k = 0; k < 13; k++) |
|
sim[j][k] -= x*sim[i][k]; |
|
} |
|
} |
|
} |
|
|
|
dumpmatrix(sim); |
|
|
|
/* Next, substitute in the unknowns. */ |
|
for (i = 12-1; i >= 0; i--) { |
|
var[i] = sim[i][12]; |
|
for (j = i+1; j < 12; j++) |
|
var[i] -= var[j] * sim[i][j]; |
|
var[i] /= sim[i][i]; |
|
} |
|
} |
|
|
|
/* In: Guess, length, angle, space for solutions */ |
|
void solvetriangle(double c, double a, double A, double *solp, double *soln) |
|
{ |
|
double root; |
|
double cosA; |
|
double med; |
|
|
|
cosA = cos(A); |
|
med = 4*c*c*cosA*cosA - 4*(c*c-a*a); |
|
root = sqrt(med); |
|
|
|
if (isnan(root)) |
|
/* sqrt() of a negative number */ |
|
if (med > -0.000000001) |
|
root = 0; |
|
|
|
*solp = (2*c*cosA + root)/2; |
|
*soln = (2*c*cosA - root)/2; |
|
} |
|
|
|
double try(int n, double dguess, double a, double b, double c, double A, double B, double C) |
|
{ |
|
double s1, s2; |
|
double e, f, d; |
|
|
|
solvetriangle(dguess, a, A, &s1, &s2); |
|
e = (n>=4?s2:s1); |
|
n = n % 4; |
|
solvetriangle(e, c, C, &s1, &s2); |
|
f = (n>=2?s2:s1); |
|
n = n % 2; |
|
solvetriangle(f, b, B, &s1, &s2); |
|
d = (n>=1?s2:s1); |
|
|
|
return d; |
|
} |
|
|
|
void getsolution(int n, double dguess, double a, double b, double c, double A, double B, double C, double *e, double *f) |
|
{ |
|
double s1, s2; |
|
|
|
solvetriangle(dguess, a, A, &s1, &s2); |
|
*e = (n>=4?s2:s1); |
|
n = n % 4; |
|
solvetriangle(*e, c, C, &s1, &s2); |
|
*f = (n>=2?s2:s1); |
|
} |
|
|
|
#define DINCR 0.005 |
|
|
|
/* |
|
* A is angle opposite a, between d and e |
|
* B is angle opposite b, between d and f |
|
* C is angle opposite c, between e and f |
|
*/ |
|
int trysolvetetra(int n, double a, double b, double c, |
|
double A, double B, double C, |
|
double *dr, double *er, double *fr) |
|
{ |
|
double dguess; |
|
double thresh = 0.000000000001; |
|
double d, lastd; |
|
double mind, maxd; |
|
double d1, d2, d3; |
|
double e, f; |
|
int found; |
|
|
|
lastd = 0.0/0.0; /* NaN */ |
|
mind = maxd = 0; /* Shut up compiler */ |
|
|
|
/* Find a bracket */ |
|
found = 0; |
|
for (dguess = 0.0; dguess < 100.0; dguess+=DINCR) { |
|
d = try(n, dguess, a, b, c, A, B, C) - dguess; |
|
if (((d >= 0) && (lastd < 0)) || ((d <= 0) && (lastd > 0))) { |
|
mind = dguess - DINCR; |
|
maxd = dguess; |
|
printf("Found bracket: (%f, %f)\n", mind, maxd); |
|
found = 1; |
|
break; |
|
} |
|
lastd = d; |
|
} |
|
if (!found) |
|
return 0; |
|
|
|
while ((maxd-mind) > thresh) { |
|
d1 = try(n, mind, a, b, c, A, B, C) - mind; |
|
d2 = try(n, (mind+maxd)/2, a, b, c, A, B, C) - (mind+maxd)/2; |
|
d3 = try(n, maxd, a, b, c, A, B, C) - maxd; |
|
if (((d2 >= 0) && (d1 < 0)) || ((d2 < 0) && (d1 >= 0))) |
|
maxd = (mind+maxd)/2; |
|
else |
|
mind = (mind+maxd)/2; |
|
} |
|
|
|
d = (mind+maxd)/2; |
|
|
|
getsolution(n, d, a, b, c, A, B, C, &e, &f); |
|
|
|
printf("Found solution: (%f, %f, %f)\n", d, e, f); |
|
|
|
*dr = d; |
|
*er = e; |
|
*fr = f; |
|
|
|
if (!isfinite(d)) |
|
return 0; |
|
if (!isfinite(e)) |
|
return 0; |
|
if (!isfinite(f)) |
|
return 0; |
|
if (d < 0) |
|
return 0; |
|
if (e < 0) |
|
return 0; |
|
if (f < 0) |
|
return 0; |
|
return 1; |
|
} |
|
|
|
int solvetetra(double a, double b, double c, |
|
double A, double B, double C, |
|
double *dr, double *er, double *fr) |
|
{ |
|
int i; |
|
|
|
for (i = 0; i < 8; i++) |
|
if (trysolvetetra(i, a, b, c, A, B, C, dr, er, fr)) |
|
return 1; |
|
return 0; |
|
} |
|
|
|
int map3d_calibrate(int light) |
|
{ |
|
double v1[3], v2[3], v3[3], p4[3]; |
|
double angle1, angle2, angle3; |
|
double a, b, c, d, e, f; |
|
double pAB[3], pBC[3]; |
|
double axis1[3], axis2[3], axis3[3]; |
|
double axm1, axm2, axm3; |
|
double hypot, alpha, beta, gamma, delta; |
|
double sim[12][13]; |
|
double var[12]; |
|
double pv[3], tv[3]; |
|
int success, i; |
|
|
|
/* |
|
* First, create unit vectors in the directions of the |
|
* pan & tilt values given |
|
*/ |
|
unitvector(v1, map3d_cal[light].pan[0], map3d_cal[light].tilt[0]); |
|
unitvector(v2, map3d_cal[light].pan[1], map3d_cal[light].tilt[1]); |
|
unitvector(v3, map3d_cal[light].pan[2], map3d_cal[light].tilt[2]); |
|
|
|
/* |
|
* Now, we need the angles between them |
|
*/ |
|
angle1 = acos(dotproduct(v1, v2)); |
|
angle2 = acos(dotproduct(v2, v3)); |
|
angle3 = acos(dotproduct(v3, v1)); |
|
|
|
printf("angles (%f, %f, %f)\n", DEG(angle1), DEG(angle2), DEG(angle3)); |
|
|
|
/* |
|
* And the lengths of the edges which we know |
|
*/ |
|
a = PYTHAG3(map3d_cal[light].cp[0], map3d_cal[light].cp[1]); |
|
b = PYTHAG3(map3d_cal[light].cp[1], map3d_cal[light].cp[2]); |
|
c = PYTHAG3(map3d_cal[light].cp[2], map3d_cal[light].cp[0]); |
|
|
|
/* Solve the tetrahedron */ |
|
success = solvetetra(a, b, c, angle1, angle2, angle3, &d, &e, &f); |
|
if (!success) { |
|
printf("failed to solve tetrahedron\n"); |
|
return 0; |
|
} |
|
|
|
/* Multiply the vectors by their magnitudes */ |
|
for (i = 0; i < 3; i++) { |
|
v1[i] *= e; |
|
v2[i] *= d; |
|
v3[i] *= f; |
|
} |
|
|
|
/* |
|
* Find two vectors to define the triangle between |
|
* the calibration points |
|
*/ |
|
for (i = 0; i < 3; i++) { |
|
pAB[i] = map3d_cal[light].cp[1][i]-map3d_cal[light].cp[0][i]; |
|
pBC[i] = map3d_cal[light].cp[2][i]-map3d_cal[light].cp[1][i]; |
|
} |
|
|
|
/* |
|
* Create some perpendicular vectors in terms of which we can |
|
* calculate a vector to the fourth point |
|
*/ |
|
axis1[0] = pAB[0]; |
|
axis1[1] = pAB[1]; |
|
axis1[2] = pAB[2]; |
|
normalise(axis1); |
|
crossproduct(axis1, pBC, axis2); |
|
normalise(axis2); |
|
crossproduct(axis1, axis2, axis3); |
|
normalise(axis3); |
|
|
|
/* |
|
* Now we do some trigonometry to find out the distance to |
|
* the fourth point in terms of the three axes |
|
*/ |
|
beta = asin(d*sin(angle1)/a); |
|
gamma = asin(f*sin(angle3)/c); |
|
delta = acos(((a*a)+(c*c)-(b*b))/(2*a*c)); |
|
|
|
alpha = acos((cos(gamma)-cos(beta)*cos(delta))/(sin(beta)*sin(delta))); |
|
|
|
hypot = e*sin(beta); |
|
axm1 = e*cos(beta); |
|
axm2 = hypot*sin(alpha); |
|
axm3 = hypot*cos(alpha); |
|
|
|
/* Now we have the magnitudes, let's get the vectors */ |
|
for (i = 0; i < 3; i++) { |
|
axis1[i] *= axm1; |
|
axis2[i] *= axm2; |
|
axis3[i] *= axm3; |
|
} |
|
|
|
/* |
|
* Now we can simply add these vectors to point A |
|
* to get the fourth point |
|
*/ |
|
for (i = 0; i < 3; i++) |
|
p4[i] = map3d_cal[light].cp[0][i] + axis1[i] + |
|
axis2[i] + axis3[i]; |
|
|
|
/* |
|
* Now we can construct a matrix to represent 12 simultaneous |
|
* equations, which we then solve to get our transformation matrix. |
|
*/ |
|
bzero(sim, sizeof(sim)); |
|
|
|
/* First point */ |
|
sim[0][0] = map3d_cal[light].cp[0][0]; |
|
sim[0][1] = map3d_cal[light].cp[0][1]; |
|
sim[0][2] = map3d_cal[light].cp[0][2]; |
|
sim[0][9] = 1; |
|
sim[0][12] = v1[0]; |
|
|
|
sim[1][3] = map3d_cal[light].cp[0][0]; |
|
sim[1][4] = map3d_cal[light].cp[0][1]; |
|
sim[1][5] = map3d_cal[light].cp[0][2]; |
|
sim[1][10] = 1; |
|
sim[1][12] = v1[1]; |
|
|
|
sim[2][6] = map3d_cal[light].cp[0][0]; |
|
sim[2][7] = map3d_cal[light].cp[0][1]; |
|
sim[2][8] = map3d_cal[light].cp[0][2]; |
|
sim[2][11] = 1; |
|
sim[2][12] = v1[2]; |
|
|
|
/* Second point */ |
|
sim[3][0] = map3d_cal[light].cp[1][0]; |
|
sim[3][1] = map3d_cal[light].cp[1][1]; |
|
sim[3][2] = map3d_cal[light].cp[1][2]; |
|
sim[3][9] = 1; |
|
sim[3][12] = v2[0]; |
|
|
|
sim[4][3] = map3d_cal[light].cp[1][0]; |
|
sim[4][4] = map3d_cal[light].cp[1][1]; |
|
sim[4][5] = map3d_cal[light].cp[1][2]; |
|
sim[4][10] = 1; |
|
sim[4][12] = v2[1]; |
|
|
|
sim[5][6] = map3d_cal[light].cp[1][0]; |
|
sim[5][7] = map3d_cal[light].cp[1][1]; |
|
sim[5][8] = map3d_cal[light].cp[1][2]; |
|
sim[5][11] = 1; |
|
sim[5][12] = v2[2]; |
|
|
|
/* Third point */ |
|
sim[6][0] = map3d_cal[light].cp[2][0]; |
|
sim[6][1] = map3d_cal[light].cp[2][1]; |
|
sim[6][2] = map3d_cal[light].cp[2][2]; |
|
sim[6][9] = 1; |
|
sim[6][12] = v3[0]; |
|
|
|
sim[7][3] = map3d_cal[light].cp[2][0]; |
|
sim[7][4] = map3d_cal[light].cp[2][1]; |
|
sim[7][5] = map3d_cal[light].cp[2][2]; |
|
sim[7][10] = 1; |
|
sim[7][12] = v3[1]; |
|
|
|
sim[8][6] = map3d_cal[light].cp[2][0]; |
|
sim[8][7] = map3d_cal[light].cp[2][1]; |
|
sim[8][8] = map3d_cal[light].cp[2][2]; |
|
sim[8][11] = 1; |
|
sim[8][12] = v3[2]; |
|
|
|
/* Fourth point */ |
|
sim[9][0] = p4[0]; |
|
sim[9][1] = p4[1]; |
|
sim[9][2] = p4[2]; |
|
sim[9][9] = 1; |
|
sim[9][12] = 0; |
|
|
|
sim[10][3] = p4[0]; |
|
sim[10][4] = p4[1]; |
|
sim[10][5] = p4[2]; |
|
sim[10][10] = 1; |
|
sim[10][12] = 0; |
|
|
|
sim[11][6] = p4[0]; |
|
sim[11][7] = p4[1]; |
|
sim[11][8] = p4[2]; |
|
sim[11][11] = 1; |
|
sim[11][12] = 0; |
|
|
|
eliminate(sim, var); |
|
|
|
map3d_cal[light].M[0][0] = var[0]; |
|
map3d_cal[light].M[1][0] = var[1]; |
|
map3d_cal[light].M[2][0] = var[2]; |
|
map3d_cal[light].M[0][1] = var[3]; |
|
map3d_cal[light].M[1][1] = var[4]; |
|
map3d_cal[light].M[2][1] = var[5]; |
|
map3d_cal[light].M[0][2] = var[6]; |
|
map3d_cal[light].M[1][2] = var[7]; |
|
map3d_cal[light].M[2][2] = var[8]; |
|
map3d_cal[light].M[3][0] = var[9]; |
|
map3d_cal[light].M[3][1] = var[10]; |
|
map3d_cal[light].M[3][2] = var[11]; |
|
|
|
printf("%f\t%f\t%f\t\t%f\n", var[0], var[3], var[6], var[9]); |
|
printf("%f\t%f\t%f\t\t%f\n", var[1], var[4], var[7], var[10]); |
|
printf("%f\t%f\t%f\t\t%f\n", var[2], var[5], var[8], var[11]); |
|
|
|
printf("Calibration points are:\n"); |
|
multiply(light, map3d_cal[light].cp[0], tv); |
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", map3d_cal[light].cp[0][0], map3d_cal[light].cp[0][1], map3d_cal[light].cp[0][2], tv[0], tv[1], tv[2]); |
|
multiply(light, map3d_cal[light].cp[1], tv); |
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", map3d_cal[light].cp[1][0], map3d_cal[light].cp[1][1], map3d_cal[light].cp[1][2], tv[0], tv[1], tv[2]); |
|
multiply(light, map3d_cal[light].cp[2], tv); |
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", map3d_cal[light].cp[2][0], map3d_cal[light].cp[2][1], map3d_cal[light].cp[2][2], tv[0], tv[1], tv[2]); |
|
multiply(light, p4, tv); |
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", p4[0], p4[1], p4[2], tv[0], tv[1], tv[2]); |
|
for (i = 0; i < 10; i++) { |
|
pv[0] = 0; |
|
pv[1] = (double)i/10.0; |
|
pv[2] = 0; |
|
multiply(light, pv, tv); |
|
printf("(%f, %f, %f) => (%f, %f, %f)\n", pv[0], pv[1], pv[2], tv[0], tv[1], tv[2]); |
|
} |
|
return 1; |
|
} |
|
|
|
/* Set parameters based on position (x, y, z) and direction (tx, ty, tz) */ |
|
/* Temp: x, y = pan, tilt measured to (0, 0, 0) |
|
tx, ty = pan, tilt of light fixture |
|
tz = distance from light fixture to (0, 0, 0) |
|
*/ |
|
void map3d_setparams(int light, int opan, int otilt, double lpan, double ltilt, double dist) |
|
{ |
|
double n[3]; |
|
double up[3]; |
|
double right[3]; |
|
double v[3]; |
|
double op, ot; |
|
|
|
op = PANRANGE * ((double)opan - PANOFFSET) / PANMAX; |
|
ot = TILTRANGE * ((double)otilt - TILTOFFSET) / TILTMAX; |
|
|
|
unitvector(v, op, ot); |
|
unitvector(n, lpan, ltilt); |
|
|
|
up[0] = 0; |
|
up[1] = (n[1] + sqrt(n[1]*n[1]+4*n[2]*n[2])) / |
|
(4*n[2]); |
|
up[2] = -up[1]*n[1]/n[2]; |
|
normalise(up); |
|
|
|
crossproduct(n, up, right); |
|
normalise(right); |
|
|
|
printf("n:\t%f\t%f\t%f\n", n[0], n[1], n[2]); |
|
printf("up: \t%f\t%f\t%f\n", up[0], up[1], up[2]); |
|
printf("right: \t%f\t%f\t%f\n", right[0], right[1], right[2]); |
|
printf("\n"); |
|
|
|
/* Construct matrix */ |
|
|
|
map3d_cal[light].M[0][0] = right[0]; |
|
map3d_cal[light].M[0][1] = right[1]; |
|
map3d_cal[light].M[0][2] = right[2]; |
|
map3d_cal[light].M[1][0] = up[0]; |
|
map3d_cal[light].M[1][1] = up[1]; |
|
map3d_cal[light].M[1][2] = up[2]; |
|
map3d_cal[light].M[2][0] = n[0]; |
|
map3d_cal[light].M[2][1] = n[1]; |
|
map3d_cal[light].M[2][2] = n[2]; |
|
map3d_cal[light].M[3][0] = dist*v[0]; |
|
map3d_cal[light].M[3][1] = dist*v[1]; |
|
map3d_cal[light].M[3][2] = dist*v[2]; |
|
|
|
printf("\t%f\t%f\t%f\t\t%f\n", map3d_cal[light].M[0][0], map3d_cal[light].M[0][1], map3d_cal[light].M[0][2], map3d_cal[light].M[3][0]); |
|
printf("\t%f\t%f\t%f\t\t%f\n", map3d_cal[light].M[1][0], map3d_cal[light].M[1][1], map3d_cal[light].M[1][2], map3d_cal[light].M[3][1]); |
|
printf("\t%f\t%f\t%f\t\t%f\n", map3d_cal[light].M[2][0], map3d_cal[light].M[2][1], map3d_cal[light].M[2][2], map3d_cal[light].M[3][2]); |
|
printf("\n"); |
|
|
|
}
|
|
|