diff options
author | vg <vgm+dev@devys.org> | 2020-07-07 16:24:01 +0200 |
---|---|---|
committer | vg <vgm+dev@devys.org> | 2020-07-07 16:24:01 +0200 |
commit | 66dcf910bd4744d8ced56cb9586aa937a1a2d4c5 (patch) | |
tree | df4dca1ae4af1e5df0be0d1f4f2cd0d54751f8e8 /instructables/cube_pc/draw.c | |
download | hic-master.tar.gz hic-master.tar.bz2 hic-master.zip |
Diffstat (limited to 'instructables/cube_pc/draw.c')
-rw-r--r-- | instructables/cube_pc/draw.c | 682 |
1 files changed, 682 insertions, 0 deletions
diff --git a/instructables/cube_pc/draw.c b/instructables/cube_pc/draw.c new file mode 100644 index 0000000..549d109 --- /dev/null +++ b/instructables/cube_pc/draw.c @@ -0,0 +1,682 @@ +#include "draw.h" +#include "draw_3d.h" +#include <string.h> + + +void setvoxel(int x, int y, int z) +{ + if (inrange(x,y,z)) + cube[y][z] |= (1 << x); + +} + +void tmpsetvoxel(int x, int y, int z) +{ + if (inrange(x,y,z)) + fb[y][z] |= (1 << x); +} + +void clrvoxel(int x, int y, int z) +{ + if (inrange(x,y,z)) + cube[y][z] &= ~(1 << x); +} + +void tmpclrvoxel(int x, int y, int z) +{ + if (inrange(x,y,z)) + fb[y][z] &= ~(1 << x); +} + +// This function validates that we are drawing inside the cube. +unsigned char inrange(int x, int y, int z) +{ + if (x >= 0 && x < 8 && y >= 0 && y < 8 && z >= 0 && z < 8) + { + return 0x01; + } else + { + // One of the coordinates was outside the cube. + return 0x00; + } +} + +// Get the current status of a voxel +unsigned char getvoxel(int x, int y, int z) +{ + if (inrange(x,y,z)) + { + if (cube[y][z] & (1 << x)) + { + return 0x01; + } else + { + return 0x00; + } + } else + { + return 0x00; + } +} + +void altervoxel(int x, int y, int z, int state) +{ + if (state == 1) + { + setvoxel(x,y,z); + } else + { + clrvoxel(x,y,z); + } +} + +// Flip the state of a voxel. +// If the voxel is 1, its turned into a 0, and vice versa. +void flpvoxel(int x, int y, int z) +{ + if (inrange(x, y, z)) + cube[y][z] ^= (1 << x); +} + +// Makes sure x1 is alwas smaller than x2 +void argorder(int ix1, int ix2, int *ox1, int *ox2) +{ + if (ix1>ix2) + { + int tmp; + tmp = ix1; + ix1= ix2; + ix2 = tmp; + } + *ox1 = ix1; + *ox2 = ix2; +} + +void setplane_z (int z) +{ + int i; + if (z>=0 && z<8) + { + for (i=0;i<8;i++) + cube[i][z] = 0xff; + } +} + + +void clrplane_z (int z) +{ + int i; + if (z>=0 && z<8) + { + for (i=0;i<8;i++) + cube[i][z] = 0x00; + } +} + +void setplane_x (int x) +{ + int z; + int y; + if (x>=0 && x<8) + { + for (z=0;z<8;z++) + { + for (y=0;y<8;y++) + { + cube[y][z] |= (1 << x); + } + } + } +} + +void clrplane_x (int x) +{ + int z; + int y; + if (x>=0 && x<8) + { + for (z=0;z<8;z++) + { + for (y=0;y<8;y++) + { + cube[y][z] &= ~(1 << x); + } + } + } +} + +void setplane_y (int y) +{ + int z; + if (y>=0 && y<8) + { + for (z=0;z<8;z++) + cube[y][z] = 0xff; + } +} + +void clrplane_y (int y) +{ + int z; + if (y>=0 && y<8) + { + for (z=0;z<8;z++) + cube[y][z] = 0x00; + } +} + + +void fill (unsigned char pattern) +{ + int z; + int y; + for (z=0;z<8;z++) + { + for (y=0;y<8;y++) + { + cube[y][z] = pattern; + } + } +} + +void tmpfill (unsigned char pattern) +{ + int z; + int y; + for (z=0;z<8;z++) + { + for (y=0;y<8;y++) + { + fb[z][y] = pattern; + } + } +} + + +void box_filled(int x1, int y1, int z1, int x2, int y2, int z2) +{ + int iy; + int iz; + + argorder(x1, x2, &x1, &x2); + argorder(y1, y2, &y1, &y2); + argorder(z1, z2, &z1, &z2); + + for (iz=z1;iz<=z2;iz++) + { + for (iy=y1;iy<=y2;iy++) + { + cube[iy][iz] |= byteline(x1,x2); + } + } + +} + +void box_walls(int x1, int y1, int z1, int x2, int y2, int z2) +{ + int iy; + int iz; + + argorder(x1, x2, &x1, &x2); + argorder(y1, y2, &y1, &y2); + argorder(z1, z2, &z1, &z2); + + for (iz=z1;iz<=z2;iz++) + { + for (iy=y1;iy<=y2;iy++) + { + if (iy == y1 || iy == y2 || iz == z1 || iz == z2) + { + cube[iy][iz] = byteline(x1,x2); + } else + { + cube[iy][iz] |= ((0x01 << x1) | (0x01 << x2)); + } + } + } + +} + + +void box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2) +{ + int iy; + int iz; + + argorder(x1, x2, &x1, &x2); + argorder(y1, y2, &y1, &y2); + argorder(z1, z2, &z1, &z2); + + // Lines along X axis + cube[y1][z1] = byteline(x1,x2); + cube[y1][z2] = byteline(x1,x2); + cube[y2][z1] = byteline(x1,x2); + cube[y2][z2] = byteline(x1,x2); + + // Lines along Y axis + for (iy=y1;iy<=y2;iy++) + { + setvoxel(x1,iy,z1); + setvoxel(x1,iy,z2); + setvoxel(x2,iy,z1); + setvoxel(x2,iy,z2); + } + + // Lines along Z axis + for (iz=z1;iz<=z2;iz++) + { + setvoxel(x1,y1,iz); + setvoxel(x1,y2,iz); + setvoxel(x2,y1,iz); + setvoxel(x2,y2,iz); + } + +} + +// Returns a byte with a row of 1's drawn in it. +// byteline(2,5) gives 0b00111100 +char byteline (int start, int end) +{ + return ((0xff<<start) & ~(0xff<<(end+1))); +} + +char flipbyte (char byte) +{ + char flop = 0x00; + + flop = (flop & 0b11111110) | (0b00000001 & (byte >> 7)); + flop = (flop & 0b11111101) | (0b00000010 & (byte >> 5)); + flop = (flop & 0b11111011) | (0b00000100 & (byte >> 3)); + flop = (flop & 0b11110111) | (0b00001000 & (byte >> 1)); + flop = (flop & 0b11101111) | (0b00010000 & (byte << 1)); + flop = (flop & 0b11011111) | (0b00100000 & (byte << 3)); + flop = (flop & 0b10111111) | (0b01000000 & (byte << 5)); + flop = (flop & 0b01111111) | (0b10000000 & (byte << 7)); + return flop; +} + +void line(int x1, int y1, int z1, int x2, int y2, int z2) +{ + float xy; // how many voxels do we move on the y axis for each step on the x axis + float xz; // how many voxels do we move on the y axis for each step on the x axis + unsigned char x,y,z; + unsigned char lasty,lastz; + + // We always want to draw the line from x=0 to x=7. + // If x1 is bigget than x2, we need to flip all the values. + if (x1>x2) + { + int tmp; + tmp = x2; x2 = x1; x1 = tmp; + tmp = y2; y2 = y1; y1 = tmp; + tmp = z2; z2 = z1; z1 = tmp; + } + + + if (y1>y2) + { + xy = (float)(y1-y2)/(float)(x2-x1); + lasty = y2; + } else + { + xy = (float)(y2-y1)/(float)(x2-x1); + lasty = y1; + } + + if (z1>z2) + { + xz = (float)(z1-z2)/(float)(x2-x1); + lastz = z2; + } else + { + xz = (float)(z2-z1)/(float)(x2-x1); + lastz = z1; + } + + + + for (x = x1; x<=x2;x++) + { + y = (xy*(x-x1))+y1; + z = (xz*(x-x1))+z1; + setvoxel(x,y,z); + } + +} + +void delay_ms(int x) +{ + memcpy(rs232_cube, cube, 64); + usleep(x*80); +} + +// Copies the contents of fb (temp cube buffer) into the rendering buffer +void tmp2cube (void) +{ + int y, z; + for (z=0;z<8;z++) + { + for (y=0;y<8;y++) + { + cube[y][z] = fb[y][z]; + } + } +} + +void shift (char axis, int direction) +{ + int i, x ,y; + int ii, iii; + int state; + + for (i = 0; i < 8; i++) + { + if (direction == -1) + { + ii = i; + } else + { + ii = (7-i); + } + + + for (x = 0; x < 8; x++) + { + for (y = 0; y < 8; y++) + { + if (direction == -1) + { + iii = ii+1; + } else + { + iii = ii-1; + } + + if (axis == AXIS_Z) + { + state = getvoxel(x,y,iii); + altervoxel(x,y,ii,state); + } + + if (axis == AXIS_Y) + { + state = getvoxel(x,iii,y); + altervoxel(x,ii,y,state); + } + + if (axis == AXIS_X) + { + state = getvoxel(iii,y,x); + altervoxel(ii,x,y,state); + } + } + } + } + + if (direction == -1) + { + i = 7; + } else + { + i = 0; + } + + for (x = 0; x < 8; x++) + { + for (y = 0; y < 8; y++) + { + if (axis == AXIS_Z) + clrvoxel(x,y,i); + + if (axis == AXIS_Y) + clrvoxel(x,i,y); + + if (axis == AXIS_X) + clrvoxel(i,y,x); + } + } +} + + + +void line_3d (int x1, int y1, int z1, int x2, int y2, int z2) +{ + int i, dx, dy, dz, l, m, n, x_inc, y_inc, z_inc, + err_1, err_2, dx2, dy2, dz2; + int pixel[3]; + pixel[0] = x1; + pixel[1] = y1; + pixel[2] = z1; + dx = x2 - x1; + dy = y2 - y1; + dz = z2 - z1; + x_inc = (dx < 0) ? -1 : 1; + l = abs(dx); + y_inc = (dy < 0) ? -1 : 1; + m = abs(dy); + z_inc = (dz < 0) ? -1 : 1; + n = abs(dz); + dx2 = l << 1; + dy2 = m << 1; + dz2 = n << 1; + if ((l >= m) && (l >= n)) { + err_1 = dy2 - l; + err_2 = dz2 - l; + for (i = 0; i < l; i++) { + //PUT_PIXEL(pixel); + setvoxel(pixel[0],pixel[1],pixel[2]); + //printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]); + if (err_1 > 0) { + pixel[1] += y_inc; + err_1 -= dx2; + } + if (err_2 > 0) { + pixel[2] += z_inc; + err_2 -= dx2; + } + err_1 += dy2; + err_2 += dz2; + pixel[0] += x_inc; + } + } else if ((m >= l) && (m >= n)) { + err_1 = dx2 - m; + err_2 = dz2 - m; + for (i = 0; i < m; i++) { + //PUT_PIXEL(pixel); + setvoxel(pixel[0],pixel[1],pixel[2]); + //printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]); + if (err_1 > 0) { + pixel[0] += x_inc; + err_1 -= dy2; + } + if (err_2 > 0) { + pixel[2] += z_inc; + err_2 -= dy2; + } + err_1 += dx2; + err_2 += dz2; + pixel[1] += y_inc; + } + } else { + err_1 = dy2 - n; + err_2 = dx2 - n; + for (i = 0; i < n; i++) { + setvoxel(pixel[0],pixel[1],pixel[2]); + //printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]); + //PUT_PIXEL(pixel); + if (err_1 > 0) { + pixel[1] += y_inc; + err_1 -= dz2; + } + if (err_2 > 0) { + pixel[0] += x_inc; + err_2 -= dz2; + } + err_1 += dy2; + err_2 += dx2; + pixel[2] += z_inc; + } + } + setvoxel(pixel[0],pixel[1],pixel[2]); + //printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]); + //PUT_PIXEL(pixel); +} + + +void line_3d_float (vertex point1, vertex point2) +{ + float x1, y1, z1, x2, y2, z2; + + x1 = point1.x; + y1 = point1.y; + z1 = point1.z; + x2 = point2.x; + y2 = point2.y; + z2 = point2.z; + + + float i; + float dx, dy, dz, l, m, n, x_inc, y_inc, z_inc, + err_1, err_2, dx2, dy2, dz2; + float pixel[3]; + pixel[0] = x1; + pixel[1] = y1; + pixel[2] = z1; + dx = x2 - x1; + dy = y2 - y1; + dz = z2 - z1; + x_inc = (dx < 0) ? -1 : 1; + l = abs(dx); + y_inc = (dy < 0) ? -1 : 1; + m = abs(dy); + z_inc = (dz < 0) ? -1 : 1; + n = abs(dz); + dx2 = l*l; + dy2 = m*m; + dz2 = n*n; + if ((l >= m) && (l >= n)) { + err_1 = dy2 - l; + err_2 = dz2 - l; + for (i = 0; i < l; i++) { + //PUT_PIXEL(pixel); + setvoxel((int)pixel[0],(int)pixel[1],(int)pixel[2]); + //printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]); + if (err_1 > 0) { + pixel[1] += y_inc; + err_1 -= dx2; + } + if (err_2 > 0) { + pixel[2] += z_inc; + err_2 -= dx2; + } + err_1 += dy2; + err_2 += dz2; + pixel[0] += x_inc; + } + } else if ((m >= l) && (m >= n)) { + err_1 = dx2 - m; + err_2 = dz2 - m; + for (i = 0; i < m; i++) { + //PUT_PIXEL(pixel); + //setvoxel(pixel[0]/scale,pixel[1]/scale,pixel[2]/scale); + setvoxel((int)pixel[0],(int)pixel[1],(int)pixel[2]); + //printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]); + if (err_1 > 0) { + pixel[0] += x_inc; + err_1 -= dy2; + } + if (err_2 > 0) { + pixel[2] += z_inc; + err_2 -= dy2; + } + err_1 += dx2; + err_2 += dz2; + pixel[1] += y_inc; + } + } else { + err_1 = dy2 - n; + err_2 = dx2 - n; + for (i = 0; i < n; i++) { + //setvoxel(pixel[0]/scale,pixel[1]/scale,pixel[2]/scale); + setvoxel((int)pixel[0],(int)pixel[1],(int)pixel[2]); + //printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]); + //PUT_PIXEL(pixel); + if (err_1 > 0) { + pixel[1] += y_inc; + err_1 -= dz2; + } + if (err_2 > 0) { + pixel[0] += x_inc; + err_2 -= dz2; + } + err_1 += dy2; + err_2 += dx2; + pixel[2] += z_inc; + } + } + //setvoxel(pixel[0]/scale,pixel[1]/scale,pixel[2]/scale); + setvoxel((int)pixel[0],(int)pixel[1],(int)pixel[2]); + //printf("Setting %i %i %i \n", pixel[0],pixel[1],pixel[2]); + //PUT_PIXEL(pixel); +} + +// Flip the cube 180 degrees along the x axis +void mirror_x (void) +{ + unsigned char buffer[8][8]; + unsigned char y,z; + + memcpy(buffer, cube, 64); // copy the current cube into a buffer. + + fill(0x00); + + for (z=0; z<8; z++) + { + for (y=0; y<8; y++) + { + cube[y][z] = flipbyte(buffer[y][z]); + } + } +} +// Flip the cube 180 degrees along the y axis. +void mirror_y (void) +{ + unsigned char buffer[8][8]; + unsigned char x,y,z; + + memcpy(buffer, cube, 64); // copy the current cube into a buffer. + + fill(0x00); + for (z=0; z<8; z++) + { + for (y=0; y<8; y++) + { + for (x=0; x<8; x++) + { + if (buffer[y][z] & (0x01 << x)) + setvoxel(x,7-y,z); + } + } + } + +} +// flip the cube 180 degrees along the z axis +void mirror_z (void) +{ + unsigned char buffer[8][8]; + unsigned char z, y; + + memcpy(buffer, cube, 64); // copy the current cube into a buffer. + + for (y=0; y<8; y++) + { + for (z=0; z<8; z++) + { + cube[7-z][y] = buffer[y][z]; + } + } +} + + + + |