#!/bin/ksh

#################################################################
#
#  OFF2TEK - A script to display OFF 3d data on the
#            Tektronix 4014 terminal. Designed specially
#            to bring 3D graphics to SDF users ;-)
#
#  by Maciek Szymanski <[email protected]>
#
#  Release M1b - corrected coordinate transformation
#                formulas.
#  Release M1a - initial public release.
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#################################################################

# process command line parameters

while [ $# -gt 0 ]
do
 case $1 in
  -s)                          # -s - scale
     SCALE=$2
     shift
     shift
     ;;
  -x)                          # -x - x offset
     XOFFS=$2
     shift
     shift
     ;;
  -y)                          # -y - y offset
     YOFFS=$2
     shift
     shift
     ;;
  -f)                          # -f - file name
     FILE=$2
     shift
     shift
     ;;
  *)                           # display usage
     cat << EOF

Usage: $0  [-s scale] [-x x offset] [-y y offset] [-f file name]
      Displays the off 3D file on the Tektronix 4014 terminal or
      a compatible emulator (eg. xterm).

EOF
     exit 0
    ;;
 esac
done


# run awk script to process off data

awk -v "SCA=${SCALE:-1}" -v "DX=${XOFFS:-512}" -v "DY=${YOFFS:-383}" \
'BEGIN {

# Parameters and constants

PI = 3.1415927;

# SCA          global scale
# DX           origin ofset
# DY

# Projection parameters

FiX = 30;
FiY = 120;
SX  = 1;
SY  = 1;
SZ  = 0.5;

# recalculate angles

Alpha = FiX * PI / 180;
Beta  = (FiY - 90) * PI / 180;

# clear terminal

clear_tek();

# Process input file

getline;

if ($0 ~ OFF) getline;

# Get data header

VERT = $1;
FAC  = $2;

# Read vertices and project to 2D

i = 0;

while(i < VERT) {

  getline;

  vx[i] = (DX + SCA * proj_x($1, $2, $3));
  vy[i] = (DY + SCA * proj_y($1, $2, $3));

  i++;
}

# Read and draw faces

i = 0;

while(i < FAC) {

  getline;

  n = $1;              # number of points

  j = 2;

  x0 = vx[$2];
  y0 = vy[$2];

  tek_graph();

  while (j < n + 1) {

     send_tek_xy(vx[$j], vy[$j]);
     j++;
  }

  send_tek_xy(x0, y0);

  i++;
}

}

# send coordinates in tek format

function send_tek_xy(x, y,      HiY, LoY, HiX, LoX)
{
 HiY = int(y / 32);
 LoY = int(y - HiY * 32);
 HiX = int(x / 32);
 LoX = int(x - HiX * 32);

 printf("%c%c%c%c", HiY + 32, LoY + 96, HiX + 32, LoX + 64);
}

# clear tek screen

function clear_tek()
{
 printf("\033\014");
}

# switch to graphics mode

function tek_graph()
{
 printf ("\035");
}

# functions to transform coordinates

# x,y,z -> 2d X

function proj_x(x, y, z)
{

 x = x * SX;
 y = y * SY;

 return (x * cos(Alpha) - y * sin(Beta));
}

# x,y,z -> 2d Y

function proj_y(x, y , z)
{

 x = x * SX;
 y = y * SY;
 z = z * SZ;

 return x * sin(Alpha) + y * cos(Beta) + z;

}' $FILE