[comp.sources.misc] v16i006: sipp 2.0 - a library for 3D graphics, Part02/06

kent@sparky.IMD.Sterling.COM (Kent Landfield) (01/03/91)

Submitted-by: ingwa@isy.liu.se (Inge Wallin)
Posting-number: Volume 16, Issue 6
Archive-name: sipp2.0/part02

#!/bin/sh
# This is part 02 of sipp-2.0
# ============= libsipp/bumpy.c ==============
if test ! -d 'libsipp'; then
    echo 'x - creating directory libsipp'
    mkdir 'libsipp'
fi
if test -f 'libsipp/bumpy.c' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/bumpy.c (File already exists)'
else
echo 'x - extracting libsipp/bumpy.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/bumpy.c' &&
/*
X * erode shader - simulates an eroded surface using noise
X */
X
#include <math.h>
#include <stdio.h>
X
#include "sipp.h"
#include "geometric.h"
#include "noise.h"
#include "shaders.h"
X
X
extern bool noise_ready;
X
X
void
bumpy_shader(nx, ny, nz, u, v, w, view_vec, lights, bd, color)
X    double        nx, ny, nz;
X    double        u, v, w;
X    Vector        view_vec;
X    Lightsource  *lights;
X    Bumpy_desc   *bd;
X    Color        *color;
{
X    Vector     tmp;
X    double     len;
X    double     no;
X
X    if (!noise_ready) {
X        noise_init();
X    }
X
X    tmp.x = u * bd->scale;
X    tmp.y = v * bd->scale;
X    tmp.z = w * bd->scale;
X
X    if ((bd->bumpflag && bd->holeflag)
X          || ((no = noise(tmp)) < 0.0 && bd->bumpflag)
X          || (no > 0.0 && bd->holeflag)) {
X        tmp = Dnoise(tmp);
X        len = sqrt(nx * nx + ny * ny + nz * nz);
X        nx = nx / len + tmp.x;
X        ny = ny / len + tmp.y;
X        nz = nz / len + tmp.z;
X    }
X
X    bd->shader(nx, ny, nz, u, v, w, view_vec, lights, bd->surface, color);
}
SHAR_EOF
chmod 0644 libsipp/bumpy.c ||
echo 'restore of libsipp/bumpy.c failed'
Wc_c="`wc -c < 'libsipp/bumpy.c'`"
test 1027 -eq "$Wc_c" ||
	echo 'libsipp/bumpy.c: original size 1027, current size' "$Wc_c"
fi
# ============= libsipp/cylinder.c ==============
if test -f 'libsipp/cylinder.c' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/cylinder.c (File already exists)'
else
echo 'x - extracting libsipp/cylinder.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/cylinder.c' &&
#include <xalloca.h>
#include <math.h>
X
#include <sipp.h>
X
X
Object *
sipp_cylinder(radius, length, res, surface, shader)
X    double  radius;
X    double  length;
X    int     res;
X    void   *surface;
X    Shader *shader;
{
X    Object *cylinder;
X    double *x_arr;
X    double *y_arr;
X    int     i;
X
X    x_arr = (double *)alloca(res * sizeof(double));
X    y_arr = (double *)alloca(res * sizeof(double));
X
X    for (i = 0; i < res; i++) {
X        x_arr[i] = radius * cos(i * 2.0 * M_PI / res);
X        y_arr[i] = radius * sin(i * 2.0 * M_PI / res);
X    }
X
X    cylinder = object_create();
X
X    /* Create the outer surface */
X    for (i = 0; i < res; i++) {
X        vertex_tx_push(x_arr[i], y_arr[i], -length / 2.0, 
X                       x_arr[i], y_arr[i], -length / 2.0);
X        vertex_tx_push(x_arr[(i + 1) % res], y_arr[(i + 1) % res],
X                       -length / 2.0, 
X                       x_arr[(i + 1) % res], y_arr[(i + 1) % res],
X                       -length / 2.0);
X        vertex_tx_push(x_arr[(i + 1) % res], y_arr[(i + 1) % res],
X                       length / 2.0, 
X                       x_arr[(i + 1) % res], y_arr[(i + 1) % res],
X                       length / 2.0);
X        vertex_tx_push(x_arr[i], y_arr[i], length / 2.0, 
X                       x_arr[i], y_arr[i], length / 2.0);
X        polygon_push();
X    }
X    object_add_surface(cylinder, surface_create(surface, shader));
X
X    /* Create the bottom lid */
X    for (i = res - 1; i >= 0; i--) {
X        vertex_tx_push(x_arr[i], y_arr[i], -length / 2.0, 
X                       x_arr[i], y_arr[i], -length / 2.0);
X    }
X    polygon_push();
X    object_add_surface(cylinder, surface_create(surface, shader));
X
X    /* Create the top lid. */
X    for (i = 0; i < res; i++) {
X        vertex_tx_push(x_arr[i], y_arr[i], length / 2.0, 
X                       x_arr[i], y_arr[i], length / 2.0);
X    }
X    polygon_push();
X    object_add_surface(cylinder, surface_create(surface, shader));
X
X    return cylinder;
}
SHAR_EOF
chmod 0644 libsipp/cylinder.c ||
echo 'restore of libsipp/cylinder.c failed'
Wc_c="`wc -c < 'libsipp/cylinder.c'`"
test 1981 -eq "$Wc_c" ||
	echo 'libsipp/cylinder.c: original size 1981, current size' "$Wc_c"
fi
# ============= libsipp/ellipsoid.c ==============
if test -f 'libsipp/ellipsoid.c' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/ellipsoid.c (File already exists)'
else
echo 'x - extracting libsipp/ellipsoid.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/ellipsoid.c' &&
#include <xalloca.h>
#include <math.h>
X
#include <sipp.h>
X
X
Object *
sipp_ellipsoid(x_rad, y_rad, z_rad, res, surface, shader)
X    double  x_rad;
X    double  y_rad;
X    double  z_rad;
X    int     res;
X    void   *surface;
X    Shader *shader;
{
X    int      i, j;
X    double   factor;
X    double   factor1;
X    double   factor2;
X    double   zradprim;
X    double   zradprim1;
X    double   zradprim2;
X    double  *x_arr;
X    double  *y_arr;
X    Object  *ellipsoid;
X    
X    /* Odd resolutions make ugly spheres since the poles will be */
X    /* different in size. */
X    if (res & 1) {
X        res++;
X    }
X
X    /* Create two arrays with the coordinates of the points */
X    /* around the perimeter at Z = 0 */
X    x_arr = (double *) alloca(res * sizeof(double));
X    y_arr = (double *) alloca(res * sizeof(double));
X    for (i = 0; i < res; i++) {
X        x_arr[i] = x_rad * cos(i * 2.0 * M_PI / res);
X        y_arr[i] = y_rad * sin(i * 2.0 * M_PI / res);
X    }
X
X    /* Create the top pole */
X    factor = sin(2.0 * M_PI / res);
X    zradprim = z_rad * cos(2.0 * M_PI / res);
X    for (i = 0; i < res; i++) {
X        vertex_tx_push(x_arr[i] * factor, y_arr[i] * factor, zradprim, 
X                       x_arr[i] * factor, y_arr[i] * factor, zradprim);
X        vertex_tx_push(factor * x_arr[(i + 1) % res],
X                       factor * y_arr[(i + 1) % res],
X                       zradprim, 
X                       factor * x_arr[(i + 1) % res],
X                       factor * y_arr[(i + 1) % res],
X                       zradprim);
X        vertex_tx_push(0.0, 0.0, z_rad, 0.0, 0.0, z_rad);
X        polygon_push();
X    }
X
X    /* Create the surface between the poles. */
X    factor2 = factor;
X    zradprim2 = zradprim;
X    for (j = 1; j < res / 2 - 1; j++) {
X        factor1 = factor2;
X        factor2 = sin((j + 1) * M_PI / (res / 2));
X        zradprim1 = zradprim2;
X        zradprim2 = z_rad * cos((j + 1) * M_PI / (res / 2));
X
X        for (i = 0; i < res; i++) {
X            vertex_tx_push(factor1 * x_arr[i], factor1 * y_arr[i], zradprim1, 
X                           factor1 * x_arr[i], factor1 * y_arr[i], zradprim1);
X            vertex_tx_push(factor2 * x_arr[i], factor2 * y_arr[i], zradprim2, 
X                           factor2 * x_arr[i], factor2 * y_arr[i], zradprim2);
X            vertex_tx_push(factor2 * x_arr[(i + 1) % res], 
X                           factor2 * y_arr[(i + 1) % res], zradprim2, 
X                           factor2 * x_arr[(i + 1) % res],
X                           factor2 * y_arr[(i + 1) % res], zradprim2);
X            vertex_tx_push(factor1 * x_arr[(i + 1) % res], 
X                           factor1 * y_arr[(i + 1) % res], zradprim1, 
X                           factor1 * x_arr[(i + 1) % res],
X                           factor1 * y_arr[(i + 1) % res], zradprim1);
X            polygon_push();
X        }
X    }
X
X    /* Create the bottom pole */
X    factor = sin(2.0 * M_PI / res);
X    zradprim = -z_rad * cos(2.0 * M_PI / res);
X    for (i = 0; i < res; i++) {
X        vertex_tx_push(x_arr[(i + 1) % res] * factor,
X                       y_arr[(i + 1) % res] * factor,
X                       zradprim, 
X                       x_arr[(i + 1) % res] * factor,
X                       y_arr[(i + 1) % res] * factor,
X                       zradprim);
X        vertex_tx_push(x_arr[i] * factor, y_arr[i] * factor, zradprim, 
X                       x_arr[i] * factor, y_arr[i] * factor, zradprim);
X        vertex_tx_push(0.0, 0.0, -z_rad, 0.0, 0.0, -z_rad);
X        polygon_push();
X    }
X
X    ellipsoid = object_create();
X    object_add_surface(ellipsoid, surface_create(surface, shader));
X
X    return ellipsoid;
}
X
X
Object *
sipp_sphere(radius, res, surface, shader)
X    double  radius;
X    int     res;
X    void   *surface;
X    Shader *shader;
{
X    return sipp_ellipsoid(radius, radius, radius, res, surface, shader);
}
SHAR_EOF
chmod 0644 libsipp/ellipsoid.c ||
echo 'restore of libsipp/ellipsoid.c failed'
Wc_c="`wc -c < 'libsipp/ellipsoid.c'`"
test 3850 -eq "$Wc_c" ||
	echo 'libsipp/ellipsoid.c: original size 3850, current size' "$Wc_c"
fi
# ============= libsipp/geometric.c ==============
if test -f 'libsipp/geometric.c' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/geometric.c (File already exists)'
else
echo 'x - extracting libsipp/geometric.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/geometric.c' &&
/*
X * File: geometric.c
X *
X * Matrixes, transformations and coordinates.
X */
X
#include <stdio.h>
#include <math.h>
#include "sipp.h"
#include "geometric.h"
X
X
X
/* =================================================================== */
X
/*
X * Allocate a new matrix, and if INITMAT != NULL copy the contents
X * of INITMAT to the new matrix.
X */
X
Transf_mat *
new_matrix(initmat)
X    Transf_mat  * initmat;
{
X    Transf_mat  * mat;
X
X    mat = (Transf_mat *) malloc(sizeof(Transf_mat));
X    if (initmat != NULL)
X	MatCopy(mat, initmat);
X
X    return mat;
}
X
X
/* =================================================================== */
/*          Transformation routines (see also geometric.h)             */
X
X
/*
X * Normalize a vector.
X */
X
void
vecnorm(vec)
X    Vector  *vec;
{
X    double   len;
X
X    len =  VecLen(*vec);
X    if (len == 0.0)
X	fprintf(stderr, "vecnorm(): Vector has length 0!\n");
X    else
X	VecScalMul(*vec, 1.0 / len, *vec);
}
X
X
X
/*
X * Set MAT to the transformation matrix that represents the 
X * concatenation between the previous transformation in MAT
X * and a translation along the Vector VEC.
X *
X * [a  b  c  0]   [ 1  0  0  0]     [ a     b     c    0]
X * [d  e  f  0]   [ 0  1  0  0]     [ d     e     f    0]
X * [g  h  i  0] * [ 0  0  1  0]  =  [ g     h     i    0]
X * [j  k  l  1]   [Tx Ty Tz  1]     [j+Tx  k+Ty  l+Tz  1]
X */
X
void
mat_translate(mat,  dx,  dy,  dz)
X    Transf_mat  * mat;
X    double        dx;
X    double        dy; 
X    double        dz;
{
X    mat->mat[3][0] += dx;
X    mat->mat[3][1] += dy;
X    mat->mat[3][2] += dz;
}
X
X
X
/*
X * Set MAT to the transformation matrix that represents the 
X * concatenation between the previous transformation in MAT
X * and a rotation with the angle ANG around the X axis.
X *
X * [a  b  c  0]   [1   0   0  0]     [a  b*Ca-c*Sa  b*Sa+c*Ca  0]
X * [d  e  f  0]   [0  Ca  Sa  0]     [d  e*Ca-f*Sa  e*Sa+f*Ca  0]
X * [g  h  i  0] * [0 -Sa  Ca  0]  =  [g  h*Ca-i*Sa  h*Sa+i*Ca  0]
X * [j  k  l  1]   [0   0   0  1]     [j  k*Ca-l*Sa  k*Se+l*Ca  1]
X */
X
void
mat_rotate_x(mat, ang)
X    Transf_mat  * mat;
X    double        ang;
{
X    double   cosang;
X    double   sinang;
X    double   tmp;
X    int      i;
X    
X    cosang = cos(ang);
X    sinang = sin(ang);
X    for (i = 0; i < 4; ++i) {
X	tmp = mat->mat[i][1];
X	mat->mat[i][1] = mat->mat[i][1] * cosang
X	               - mat->mat[i][2] * sinang;
X	mat->mat[i][2] = tmp * sinang + mat->mat[i][2] * cosang;
X    }
}
X
X
X
/*
X * Set MAT to the transformation matrix that represents the 
X * concatenation between the previous transformation in MAT
X * and a rotation with the angle ANG around the Y axis.
X *
X * [a  b  c  0]   [Ca   0 -Sa  0]     [a*Ca+c*Sa  b  -a*Sa+c*Ca  0]
X * [d  e  f  0] * [ 0   1   0  0]  =  [d*Ca+f*Sa  e  -d*Sa+f*Ca  0]
X * [g  h  i  0]   [Sa   0  Ca  0]     [g*Ca+i*Sa  h  -g*Sa+i*Ca  0]
X * [j  k  l  1]   [ 0   0   0  1]     [j*Ca+l*Sa  k  -j*Sa+l*Ca  1]
X */
X
void
mat_rotate_y(mat, ang)
X    Transf_mat  * mat;
X    double        ang;
{
X    double   cosang;
X    double   sinang;
X    double   tmp;
X    int      i;
X    
X    cosang = cos(ang);
X    sinang = sin(ang);
X    for (i = 0; i < 4; ++i) {
X	tmp = mat->mat[i][0];
X	mat->mat[i][0] = mat->mat[i][0] * cosang
X	               + mat->mat[i][2] * sinang;
X	mat->mat[i][2] = -tmp * sinang + mat->mat[i][2] * cosang;
X    }
}
X
X
X
/*
X * Set MAT to the transformation matrix that represents the 
X * concatenation between the previous transformation in MAT
X * and a rotation with the angle ANG around the Z axis.
X *
X * [a  b  c  0]   [ Ca  Sa   0  0]     [a*Ca-b*Sa  a*Sa+b*Ca  c  0]
X * [d  e  f  0]   [-Sa  Ca   0  0]     [d*Ca-e*Sa  d*Sa+e*Ca  f  0]
X * [g  h  i  0] * [  0   0   1  0]  =  [g*Ca-h*Sa  g*Sa+h*Ca  i  0]
X * [j  k  l  1]   [  0   0   0  1]     [j*Ca-k*Sa  j*Sa+k*Ca  l  0]
X */
X
void
mat_rotate_z(mat, ang)
X    Transf_mat  * mat;
X    double        ang;
{
X    double   cosang;
X    double   sinang;
X    double   tmp;
X    int      i;
X    
X    cosang = cos(ang);
X    sinang = sin(ang);
X    for (i = 0; i < 4; ++i) {
X	tmp = mat->mat[i][0];
X	mat->mat[i][0] = mat->mat[i][0] * cosang
X	               - mat->mat[i][1] * sinang;
X	mat->mat[i][1] = tmp * sinang + mat->mat[i][1] * cosang;
X    }
}
X
X
X
/*
X * Set MAT to the transformation matrix that represents the
X * concatenation between the previous transformation in MAT
X * and a rotation with the angle ANG around the line represented
X * by the point POINT and the vector VECTOR.
X */
X
void
mat_rotate(mat, point, vector, ang)
X    Transf_mat  * mat;
X    Vector      * point;
X    Vector      * vector;
X    double        ang;
{
X    double   ang2;
X    double   ang3;
X
X    ang2 = atan2(vector->y, vector->x);
X    ang3 = atan2(hypot(vector->x, vector->y), vector->z);
X    mat_translate(mat, -point->x, -point->y, -point->z);
X    mat_rotate_z(mat, -ang2);
X    mat_rotate_y(mat, -ang3);
X    mat_rotate_z(mat, ang);
X    mat_rotate_z(mat, ang2);
X    mat_rotate_y(mat, ang3);
X    mat_translate(mat, point->x, point->y, point->z);
}
X
X
X
/*
X * Set MAT to the transformation matrix that represents the 
X * concatenation between the previous transformation in MAT
X * and a scaling with the scaling factors in the Vector scale.
X *
X * [a  b  c  0]   [Sx  0  0  0]     [a*Sx  b*Sy  c*Sz  0]
X * [d  e  f  0]   [ 0 Sy  0  0]     [d*Sx  e*Sy  f*Sz  0]
X * [g  h  i  0] * [ 0  0 Sz  0]  =  [g*Sx  h*Sy  i*Sz  0]
X * [j  k  l  1]   [ 0  0  0  1]     [j*Sx  k*Sy  l*Sz  1]
X */
X
void
mat_scale(mat, xscale, yscale, zscale)
X    Transf_mat  * mat;
X    double        xscale;
X    double        yscale;
X    double        zscale;
{
X    int   i;
X
X    for (i = 0; i < 4; ++i) {
X	mat->mat[i][0] *= xscale;
X	mat->mat[i][1] *= yscale;
X	mat->mat[i][2] *= zscale;
X    }
}
X
X
X
/*
X * Set MAT to the transformation matrix that represents the
X * concatenation between the previous transformation in MAT
X * and a mirroring in the plane defined by the point POINT
X * and the normal vector NORMAL.
X */
X
void
mat_mirror_plane(mat, point, norm)
X    Transf_mat  * mat;
X    Vector      * point;
X    Vector      * norm;
{
X    Transf_mat   tmp;
X    double   factor;
X
X    /* The first thing we do is to make a transformation matrix */
X    /* for mirroring through a plane with the same normal vector */
X    /* as our, but through the origin instead. */
X    factor = 2.0 / (norm->x * norm->x + norm->y * norm->y 
X		    + norm->z * norm->z);
X    
X    /* The diagonal elements. */
X    tmp.mat[0][0] = 1 - factor * norm->x * norm->x;
X    tmp.mat[1][1] = 1 - factor * norm->y * norm->y;
X    tmp.mat[2][2] = 1 - factor * norm->z * norm->z;
X    
X    /* The rest of the matrix */
X    tmp.mat[1][0] = tmp.mat[0][1] = -factor * norm->x * norm->y;
X    tmp.mat[2][0] = tmp.mat[0][2] = -factor * norm->x * norm->z;
X    tmp.mat[2][1] = tmp.mat[1][2] = -factor * norm->y * norm->z;
X    tmp.mat[3][0] = tmp.mat[3][1] = tmp.mat[3][2] = 0.0;
X
X    /* Do the actual transformation. This is done in 3 steps: */
X    /* 1) Translate the plane so that it goes through the origin. */
X    /* 2) Do the actual mirroring. */
X    /* 3) Translate it all back to the starting position. */
X    mat_translate(mat, -point->x, -point->y, -point->z);
X    mat_mul(mat, mat, &tmp);
X    mat_translate(mat, point->x, point->y, point->z);
}
X
X
X
/*
X * Multiply the Matrix A with the Matrix B, and store the result
X * into the Matrix RES. It is possible for RES to point to the 
X * same Matrix as either A or B since the result is stored into
X * a temporary during computation.
X *
X * [a b c 0]  [A B C 0]     [aA+bD+cG    aB+bE+cH    aC+bF+cI    0]
X * [d e f 0]  [D E F 0]     [dA+eD+fG    dB+eE+fH    dC+eF+fI    0]
X * [g h i 0]  [G H I 0]  =  [gA+hD+iG    gB+hE+iH    gC+hF+iI    0]
X * [j k l 1]  [J K L 1]     [jA+kD+lG+J  jB+kE+lH+K  jC+kF+lI+L  1]
X */
X
void
mat_mul(res, a, b)
X    Transf_mat  * res;
X    Transf_mat  * a;
X    Transf_mat  * b;
{
X    Transf_mat   tmp;
X    int      i;
X
X    for (i = 0; i < 4; ++i) {
X	tmp.mat[i][0] = a->mat[i][0] * b->mat[0][0]
X	              + a->mat[i][1] * b->mat[1][0] 
X	              + a->mat[i][2] * b->mat[2][0];
X	tmp.mat[i][1] = a->mat[i][0] * b->mat[0][1]
X  	              + a->mat[i][1] * b->mat[1][1] 
X	              + a->mat[i][2] * b->mat[2][1];
X	tmp.mat[i][2] = a->mat[i][0] * b->mat[0][2]
X 	              + a->mat[i][1] * b->mat[1][2]
X	              + a->mat[i][2] * b->mat[2][2];
X    }
X
X    tmp.mat[3][0] += b->mat[3][0];
X    tmp.mat[3][1] += b->mat[3][1];
X    tmp.mat[3][2] += b->mat[3][2];
X
X    MatCopy(res, &tmp);
}
X
X
X
/*
X * Transform the Point3d VEC with the transformation matrix MAT, and
X * put the result into the vector *RES.
X *
X *               [a  b  c  0]
X *               [d  e  f  0]
X * [x  y  z  1]  [g  h  i  0]  =  [ax+dy+gz+j  bx+ey+hz+k  cx+fy+iz+l  1]
X *               [j  k  l  1]
X */
X
void
point_transform(res, vec, mat)
X    Vector      * res;
X    Vector      * vec;
X    Transf_mat  * mat;
{
X    res->x = mat->mat[0][0] * vec->x + mat->mat[1][0] * vec->y 
X        + mat->mat[2][0] * vec->z + mat->mat[3][0];
X    res->y = mat->mat[0][1] * vec->x + mat->mat[1][1] * vec->y 
X        + mat->mat[2][1] * vec->z + mat->mat[3][1];
X    res->z = mat->mat[0][2] * vec->x + mat->mat[1][2] * vec->y 
X        + mat->mat[2][2] * vec->z + mat->mat[3][2];
}
X
X
/*
X * Multiply the 4x3 matrix MAT3 by the 4x4 matrix MAT4, putting the
X * result in the 4x4 matrix RES.
X */
X
void
mat_mul34(res, mat3, mat4)
X    double        res[4][4];
X    Transf_mat  * mat3;
X    double        mat4[4][4];
{
X    double tmp[4][4];
X    int    row;
X    int    col;
X    int    k;
X
X    for (row = 0; row < 4; ++row) {
X        for (col = 0; col < 4; ++col) {
X            if (row == 3) {
X                tmp[row][col] = mat4[3][col];
X            } else {
X                tmp[row][col] = 0.0;
X            }
X
X            for (k = 0; k < 3; ++k) {
X                tmp[row][col] += mat3->mat[row][k] * mat4[k][col];
X            }
X        }
X    }
X    memcpy(res, tmp, 4 * 4 * sizeof(double));
}
SHAR_EOF
chmod 0644 libsipp/geometric.c ||
echo 'restore of libsipp/geometric.c failed'
Wc_c="`wc -c < 'libsipp/geometric.c'`"
test 9833 -eq "$Wc_c" ||
	echo 'libsipp/geometric.c: original size 9833, current size' "$Wc_c"
fi
# ============= libsipp/geometric.h ==============
if test -f 'libsipp/geometric.h' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/geometric.h (File already exists)'
else
echo 'x - extracting libsipp/geometric.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/geometric.h' &&
/*
X * File: geometric.h
X *
X * All kinds of stuff with matrixes, transformations, coordinates
X * a.s.o.
X */
X
/* Make sure no multiple including */
#ifndef _GEOMETRIC_H_
#define _GEOMETRIC_H_
X
#include <math.h>
#ifndef NOMEMCPY
#include <memory.h>
#endif
X
X
/* #define PI    3.1415926535897932384626 */
X
X
/*
X * Define a homogenous transformation matrix. The first row (vector) 
X * is the new X axis, i.e. the X axis in the transformed coordinate 
X * system. The second row is the new Y axis, and so on. The last row
X * is the translation, for a transformed point.
X *
X * The reason we make surround the rows with a struct is that we
X * don't want to say (Transf_mat *) &foo[0] instead of &foo when
X * sending an address to a matrix as a parameter to a function.
X * Alas, arrays are not first class objects in C.
X */
X
X
X
/*
X * NOTE:
X * Capitalized types denote Vectors and other aggregates.
X * Lower case denote scalars.
X */
X
/* P = Pointd(x, y) */
#define MakePoint2d(P, xx, yy)	 { (P)[0]=(xx); \
X                                   (P)[1]=(yy); }
X
/* P = Point3d(x, y, z) */
#define MakePoint3d(P, xx, yy, zz) { (P)[0]=(xx); \
X                                     (P)[1]=(yy); \
X                                     (P)[2]=(zz); }
X
/* V = Vec(x, y, z) */
#define MakeVector(V, xx, yy, zz)  { (V).x=(xx); \
X                                     (V).y=(yy); \
X                                     (V).z=(zz); }
X
/* A = -A */
#define VecNegate(A)	         { (A).x=0-(A).x; \
X			           (A).y=0-(A).y; \
X			           (A).z=0-(A).z; }
X
/* return A . B */
#define VecDot(A, B)	((A).x*(B).x+(A).y*(B).y+(A).z*(B).z)
X
/* return length(A) */
#define VecLen(A)	(sqrt((double)VecDot(A, A)))
X
/* B = A */
#define VecCopy(B, A)	((B) = (A))
X
/* C = A + B */
#define VecAdd(C, A, B)	 { (C).x=(A).x+(B).x; \
X			   (C).y=(A).y+(B).y; \
X			   (C).z=(A).z+(B).z; }
X
/* C = A - B */
#define VecSub(C, A, B)	 { (C).x=(A).x-(B).x; \
X			   (C).y=(A).y-(B).y; \
X			   (C).z=(A).z-(B).z; }
X
/* C = a*A */
#define VecScalMul(C, a, A)	 { (C).x=(a)*(A).x; \
X				   (C).y=(a)*(A).y; \
X				   (C).z=(a)*(A).z; }
X
/* C = a*A + B */
#define VecAddS(C, a, A, B)	 { (C).x=(a)*(A).x+(B).x; \
X				   (C).y=(a)*(A).y+(B).y; \
X				   (C).z=(a)*(A).z+(B).z; }
X
/* C = a*A + b*B */
#define VecComb(C, a, A, b, B)	 { (C).x=(a)*(A).x+(b)*(B).x; \
X				   (C).y=(a)*(A).y+(b)*(B).y; \
X			 	   (C).z=(a)*(A).z+(b)*(B).z; }
X
/* C = A X B */
#define VecCross(C, A, B)   	 { (C).x=(A).y*(B).z-(A).z*(B).y; \
X                                   (C).y=(A).z*(B).x-(A).x*(B).z; \
X			           (C).z=(A).x*(B).y-(A).y*(B).x; }
X
X
/*-------------------------- Matrix operations -------------------------*/
X
X
/* *A = *B    N.b. A and B are pointers! */
#define MatCopy(A, B)		 (*A) = (*B)
X
X
/*--------------------- Transf_mat-Vector operations -------------------*/
X
X
/* Store a Vector into a row in a Matrix */
/* NOTE: This implementation depends on that a Vector is the same */
/*       type as a row in a Matrix!! */
#define Vec2Row(mat, row, vec)	((mat).rows[row] = vec)
X
X
/*----------------------------------------------------------------------*/
X
X
/* Function declarations for the functions in geometric.c */
X
extern void          vecnorm(/* Vector */); /* Normalize a vector */
extern Transf_mat  * new_matrix(/* Matrix * */);
extern void          mat_translate(/* Matrix *, double, double, double */);
extern void          mat_rotate_x(/* Matrix *, double */);
extern void          mat_rotate_y(/* Matrix *, double */);
extern void          mat_rotate_z(/* Matrix *, double */);
extern void          mat_rotate(/* Matrix *, Point3d *, Vector *, double */);
extern void          mat_scale(/* Matrix *, double, double, double */);
extern void          mat_mirror_plane(/* Matrix *, Point3d *, Vector * */);
extern void          mat_mul(/* Matrix *, Matrix *, Matrix * */);
extern void          mat_mul34(/* double[4][4] *, Matrix *, double[4][4] */);
extern void          point_transform(/* Point3d *, Point3d *, Matrix * */);
X
X
#endif  /* _GEOMETRIC_H_ */
SHAR_EOF
chmod 0644 libsipp/geometric.h ||
echo 'restore of libsipp/geometric.h failed'
Wc_c="`wc -c < 'libsipp/geometric.h'`"
test 4007 -eq "$Wc_c" ||
	echo 'libsipp/geometric.h: original size 4007, current size' "$Wc_c"
fi
# ============= libsipp/granite.c ==============
if test -f 'libsipp/granite.c' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/granite.c (File already exists)'
else
echo 'x - extracting libsipp/granite.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/granite.c' &&
/*
X * Granite - using a 1/f fractal noise function for color values.  
X */
X
#include <math.h>
#include <stdio.h>
X
#include "sipp.h"
#include "noise.h"
#include "shaders.h"
X
X
extern bool noise_ready;
X
X
static void 
granite (p, color, gd)
X    Vector *p;
X    Color *color;
X    Granite_desc *gd;
{
X    int i;
X    Vector v;
X    double temp, n = 0.5, freq = 1.0;
X
X    v = *p;
X    
X    for (i = 0; i < 6 ; freq *= 2.0, i++) {
X        v.x *= 4.0 * freq;
X        v.y *= 4.0 * freq;
X        v.z *= 4.0 * freq;
X        temp = 0.5 * noise(&v);
/*        temp = fabs(temp);*/
X        n += temp / freq;
X    }
X
X   color->red = gd->col1.red * n + gd->col2.red * (1.0 - n);
X   color->grn = gd->col1.grn * n + gd->col2.grn * (1.0 - n);
X   color->blu = gd->col1.blu * n + gd->col2.blu * (1.0 - n);
}
X
X
void
granite_shader(nx, ny, nz, u, v, w, view_vec, lights, gd, color)
X    double  nx, ny, nz, u, v, w;
X    Vector  view_vec;
X    Lightsource *lights;
X    Granite_desc *gd;
X    Color *color;
{
X    Vector     tmp;
X    Surf_desc  surface;
X
X    if (!noise_ready) {
X        noise_init();
X    }
X
X    tmp.x = u * gd->scale;
X    tmp.y = v * gd->scale;
X    tmp.z = w * gd->scale;
X    granite(&tmp, &surface.color, gd);
X    surface.ambient  = gd->ambient;
X    surface.specular = gd->specular;
X    surface.c3       = gd->c3;
X    basic_shader(nx, ny, nz, u, v, w, view_vec, lights, &surface, color);
}
SHAR_EOF
chmod 0644 libsipp/granite.c ||
echo 'restore of libsipp/granite.c failed'
Wc_c="`wc -c < 'libsipp/granite.c'`"
test 1373 -eq "$Wc_c" ||
	echo 'libsipp/granite.c: original size 1373, current size' "$Wc_c"
fi
# ============= libsipp/marble.c ==============
if test -f 'libsipp/marble.c' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/marble.c (File already exists)'
else
echo 'x - extracting libsipp/marble.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/marble.c' &&
/*
X * marble shader - simulates marble using noise & turbulence
X */
X
#include <math.h>
#include <stdio.h>
X
#include "sipp.h"
#include "noise.h"
#include "shaders.h"
X
X
extern bool noise_ready;
X
X
static void
marble(p, color, md)
X    Vector *p;
X    Color *color;
X    Marble_desc *md;
{
X    double x, t;
X
X    x = p->x + turbulence(p, (double)(1.0 / 100.0)) * 5;
X    x = sin(x);
X    if (x > -0.1 && x < 0.1) {
X        color->red = md->strip.red;
X        color->grn = md->strip.grn;
X        color->blu = md->strip.blu;
X    } else if (x > -0.9 && x < 0.9){
X        /* You are not supposed to understand this... */
X        t = 7.0 / 6.0 - 1.0 / (6.25 * fabs(x) + 0.375);
X        color->red = md->strip.red + t * (md->base.red - md->strip.red);
X        color->grn = md->strip.grn + t * (md->base.grn - md->strip.grn);
X        color->blu = md->strip.blu + t * (md->base.blu - md->strip.blu);
X    } else {
X        color->red = md->base.red;         
X        color->grn = md->base.grn;
X        color->blu = md->base.blu;
X    }
}
X
X
X
void
marble_shader(nx, ny, nz, u, v, w, view_vec, lights, md, color)
X    double  nx, ny, nz, u, v, w;
X    Vector  view_vec;
X    Lightsource *lights;
X    Marble_desc *md;
X    Color *color;
{
X    Vector     tmp;
X    Surf_desc  surface;
X
X    if (!noise_ready) {
X        noise_init();
X    }
X
X    tmp.x = u * md->scale;
X    tmp.y = v * md->scale;
X    tmp.z = w * md->scale;
X    marble(&tmp, &surface.color, md);
X    surface.ambient  = md->ambient;
X    surface.specular = md->specular;
X    surface.c3       = md->c3;
X    basic_shader(nx, ny, nz, u, v, w, view_vec, lights, &surface, color);
}
SHAR_EOF
chmod 0644 libsipp/marble.c ||
echo 'restore of libsipp/marble.c failed'
Wc_c="`wc -c < 'libsipp/marble.c'`"
test 1607 -eq "$Wc_c" ||
	echo 'libsipp/marble.c: original size 1607, current size' "$Wc_c"
fi
# ============= libsipp/mask.c ==============
if test -f 'libsipp/mask.c' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/mask.c (File already exists)'
else
echo 'x - extracting libsipp/mask.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/mask.c' &&
#include "sipp.h"
#include "shaders.h"
X
void
mask_shader(a, b, c, u, v, w, view_vec, lights, sd, color)
X    double  a, b, c, u, v, w;
X    Vector  view_vec;
X    Lightsource *lights;
X    Mask_desc *sd;
X    Color *color;
{
X    int  ras_x, ras_y;
X    bool mapped;
X
X    ras_x = u * sd->xscale + sd->x0;
X    ras_y = v * sd->yscale + sd->y0;
X    mapped = ((ras_x >=0 && ras_x < sd->xsize) 
X              && (ras_y >= 0 && ras_y < sd->ysize)
X              && sd->pixel_test(sd->mask, ras_x, ras_y));
X    if (mapped) {
X        sd->fg_shader(a, b, c, u, v, w, view_vec, lights, sd->fg_surface,
X                      color); 
X    } else {
X        sd->bg_shader(a, b, c, u, v, w, view_vec, lights, sd->bg_surface,
X                      color); 
X    }
}
SHAR_EOF
chmod 0644 libsipp/mask.c ||
echo 'restore of libsipp/mask.c failed'
Wc_c="`wc -c < 'libsipp/mask.c'`"
test 741 -eq "$Wc_c" ||
	echo 'libsipp/mask.c: original size 741, current size' "$Wc_c"
fi
# ============= libsipp/noise.c ==============
if test -f 'libsipp/noise.c' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/noise.c (File already exists)'
else
echo 'x - extracting libsipp/noise.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/noise.c' &&
#include <math.h>
X
#include "sipp.h"
#include "noise.h"
X
/* ================================================================ */
/*                      Noise and friends                           */
X
X
/*
X *	Noise and Dnoise routines
X *
X *	Many thanks to Jon Buller of Colorado State University for these
X *	routines.
X */
X
X
#define NUMPTS	512
#define P1	173
#define P2	263
#define P3	337
#define phi	0.6180339
X
X
bool noise_ready = FALSE;
X
static double pts[NUMPTS];
X
X
/*
X * Doubles might have values that is too large to be
X * stored in an int. If this is the case we "fold" the
X * value about MAXINT or MININT until it is of an
X * acceptable size.
X *
X * NOTE: 32 bit integers is assumed.
X */
static double
iadjust(f)
X    double f;
{
X    while ((f > 2147483647.0) || (f < -2147483648.0)) {
X        if (f > 2147483647.0) {         /* 2**31 - 1 */
X            f = (4294967294.0 - f);     /* 2**32 - 2 */
X        } else if (f < -2147483648.0){
X            f = (-4294967296.0 - f);
X        }
X    }
X    return f;
}
X
X
X
/*
X * Initialize the array of random numbers.
X * RANDOM() is defined in sipp.h
X */
void noise_init()
{
X    int i;
X    extern double drand48();
X   
X    for (i = 0; i < NUMPTS; ++i)
X        pts[i] = RANDOM();
X    noise_ready = TRUE;
}
X
X
X
double noise(v)
Vector *v;
{
X   Vector p;
X   int xi, yi, zi;
X   int xa, xb, xc, ya, yb, yc, za, zb, zc;
X   double xf, yf, zf;
X   double x2, x1, x0, y2, y1, y0, z2, z1, z0;
X   double p000, p100, p200, p010, p110, p210, p020, p120, p220;
X   double p001, p101, p201, p011, p111, p211, p021, p121, p221;
X   double p002, p102, p202, p012, p112, p212, p022, p122, p222;
X   double tmp;
X
X   p = *v;
X
X   p.x = iadjust(p.x);
X   p.y = iadjust(p.y);
X   p.z = iadjust(p.z);
X   xi = floor(p.x);
X   xa = floor(P1 * (xi * phi - floor(xi * phi)));
X   xb = floor(P1 * ((xi + 1) * phi - floor((xi + 1) * phi)));
X   xc = floor(P1 * ((xi + 2) * phi - floor((xi + 2) * phi)));
X
X   yi = floor(p.y);
X   ya = floor(P2 * (yi * phi - floor(yi * phi)));
X   yb = floor(P2 * ((yi + 1) * phi - floor((yi + 1) * phi)));
X   yc = floor(P2 * ((yi + 2) * phi - floor((yi + 2) * phi)));
X
X   zi = floor(p.z);
X   za = floor(P3 * (zi * phi - floor(zi * phi)));
X   zb = floor(P3 * ((zi + 1) * phi - floor((zi + 1) * phi)));
X   zc = floor(P3 * ((zi + 2) * phi - floor((zi + 2) * phi)));
X
X   p000 = pts[(xa + ya + za) % NUMPTS];
X   p100 = pts[(xb + ya + za) % NUMPTS];
X   p200 = pts[(xc + ya + za) % NUMPTS];
X   p010 = pts[(xa + yb + za) % NUMPTS];
X   p110 = pts[(xb + yb + za) % NUMPTS];
X   p210 = pts[(xc + yb + za) % NUMPTS];
X   p020 = pts[(xa + yc + za) % NUMPTS];
X   p120 = pts[(xb + yc + za) % NUMPTS];
X   p220 = pts[(xc + yc + za) % NUMPTS];
X   p001 = pts[(xa + ya + zb) % NUMPTS];
X   p101 = pts[(xb + ya + zb) % NUMPTS];
X   p201 = pts[(xc + ya + zb) % NUMPTS];
X   p011 = pts[(xa + yb + zb) % NUMPTS];
X   p111 = pts[(xb + yb + zb) % NUMPTS];
X   p211 = pts[(xc + yb + zb) % NUMPTS];
X   p021 = pts[(xa + yc + zb) % NUMPTS];
X   p121 = pts[(xb + yc + zb) % NUMPTS];
X   p221 = pts[(xc + yc + zb) % NUMPTS];
X   p002 = pts[(xa + ya + zc) % NUMPTS];
X   p102 = pts[(xb + ya + zc) % NUMPTS];
X   p202 = pts[(xc + ya + zc) % NUMPTS];
X   p012 = pts[(xa + yb + zc) % NUMPTS];
X   p112 = pts[(xb + yb + zc) % NUMPTS];
X   p212 = pts[(xc + yb + zc) % NUMPTS];
X   p022 = pts[(xa + yc + zc) % NUMPTS];
X   p122 = pts[(xb + yc + zc) % NUMPTS];
X   p222 = pts[(xc + yc + zc) % NUMPTS];
X
X   xf = p.x - xi;
X   x1 = xf * xf;
X   x2 = 0.5 * x1;
X   x1 = 0.5 + xf - x1;
X   x0 = 0.5 - xf + x2;
X
X   yf = p.y - yi;
X   y1 = yf * yf;
X   y2 = 0.5 * y1;
X   y1 = 0.5 + yf - y1;
X   y0 = 0.5 - yf + y2;
X
X   zf = p.z - zi;
X   z1 = zf * zf;
X   z2 = 0.5 * z1;
X   z1 = 0.5 + zf - z1;
X   z0 = 0.5 - zf + z2;
X
X   /*
X    * This expression is split up since some compilers
X    * chokes on expressions of this size.
X    */
X   tmp =  z0 * (y0 * (x0 * p000 + x1 * p100 + x2 * p200) +
X                y1 * (x0 * p010 + x1 * p110 + x2 * p210) +
X                y2 * (x0 * p020 + x1 * p120 + x2 * p220));
X   tmp += z1 * (y0 * (x0 * p001 + x1 * p101 + x2 * p201) +
X                y1 * (x0 * p011 + x1 * p111 + x2 * p211) +
X                y2 * (x0 * p021 + x1 * p121 + x2 * p221));
X   tmp += z2 * (y0 * (x0 * p002 + x1 * p102 + x2 * p202) +
X                y1 * (x0 * p012 + x1 * p112 + x2 * p212) +
X                y2 * (x0 * p022 + x1 * p122 + x2 * p222));
X
X   return tmp;
}
X
X
X
double turbulence(p, size)
X    Vector *p;
X    double size;
{
X    Vector tmp;
X    double scale = 1.0,
X           t     = 0.0;
X
X    while (scale > size) {
X        tmp.x = p->x / scale;
X        tmp.y = p->y / scale;
X        tmp.z = p->z / scale;
X        t += fabs(noise(&tmp) * scale);
X        scale /= 2.0;
X    }
X    return t;
}
X
X
X
Vector Dnoise(p)
Vector *p;
{
X   Vector v;
X   int xi, yi, zi;
X   int xa, xb, xc, ya, yb, yc, za, zb, zc;
X   double xf, yf, zf;
X   double x2, x1, x0, y2, y1, y0, z2, z1, z0;
X   double xd2, xd1, xd0, yd2, yd1, yd0, zd2, zd1, zd0;
X   double p000, p100, p200, p010, p110, p210, p020, p120, p220;
X   double p001, p101, p201, p011, p111, p211, p021, p121, p221;
X   double p002, p102, p202, p012, p112, p212, p022, p122, p222;
X
X   xi = floor(p->x);
X   xa = floor(P1 * (xi * phi - floor(xi * phi)));
X   xb = floor(P1 * ((xi + 1) * phi - floor((xi + 1) * phi)));
X   xc = floor(P1 * ((xi + 2) * phi - floor((xi + 2) * phi)));
X
X   yi = floor(p->y);
X   ya = floor(P2 * (yi * phi - floor(yi * phi)));
X   yb = floor(P2 * ((yi + 1) * phi - floor((yi + 1) * phi)));
X   yc = floor(P2 * ((yi + 2) * phi - floor((yi + 2) * phi)));
X
X   zi = floor(p->z);
X   za = floor(P3 * (zi * phi - floor(zi * phi)));
X   zb = floor(P3 * ((zi + 1) * phi - floor((zi + 1) * phi)));
X   zc = floor(P3 * ((zi + 2) * phi - floor((zi + 2) * phi)));
X
X   p000 = pts[(xa + ya + za) % NUMPTS];
X   p100 = pts[(xb + ya + za) % NUMPTS];
X   p200 = pts[(xc + ya + za) % NUMPTS];
X   p010 = pts[(xa + yb + za) % NUMPTS];
X   p110 = pts[(xb + yb + za) % NUMPTS];
X   p210 = pts[(xc + yb + za) % NUMPTS];
X   p020 = pts[(xa + yc + za) % NUMPTS];
X   p120 = pts[(xb + yc + za) % NUMPTS];
X   p220 = pts[(xc + yc + za) % NUMPTS];
X   p001 = pts[(xa + ya + zb) % NUMPTS];
X   p101 = pts[(xb + ya + zb) % NUMPTS];
X   p201 = pts[(xc + ya + zb) % NUMPTS];
X   p011 = pts[(xa + yb + zb) % NUMPTS];
X   p111 = pts[(xb + yb + zb) % NUMPTS];
X   p211 = pts[(xc + yb + zb) % NUMPTS];
X   p021 = pts[(xa + yc + zb) % NUMPTS];
X   p121 = pts[(xb + yc + zb) % NUMPTS];
X   p221 = pts[(xc + yc + zb) % NUMPTS];
X   p002 = pts[(xa + ya + zc) % NUMPTS];
X   p102 = pts[(xb + ya + zc) % NUMPTS];
X   p202 = pts[(xc + ya + zc) % NUMPTS];
X   p012 = pts[(xa + yb + zc) % NUMPTS];
X   p112 = pts[(xb + yb + zc) % NUMPTS];
X   p212 = pts[(xc + yb + zc) % NUMPTS];
X   p022 = pts[(xa + yc + zc) % NUMPTS];
X   p122 = pts[(xb + yc + zc) % NUMPTS];
X   p222 = pts[(xc + yc + zc) % NUMPTS];
X
X   xf = p->x - xi;
X   x1 = xf * xf;
X   x2 = 0.5 * x1;
X   x1 = 0.5 + xf - x1;
X   x0 = 0.5 - xf + x2;
X   xd2 = xf;
X   xd1 = 1.0 - xf - xf;
X   xd0 = xf - 1.0;
X
X   yf = p->y - yi;
X   y1 = yf * yf;
X   y2 = 0.5 * y1;
X   y1 = 0.5 + yf - y1;
X   y0 = 0.5 - yf + y2;
X   yd2 = yf;
X   yd1 = 1.0 - yf - yf;
X   yd0 = yf - 1.0;
X
X   zf = p->z - zi;
X   z1 = zf * zf;
X   z2 = 0.5 * z1;
X   z1 = 0.5 + zf - z1;
X   z0 = 0.5 - zf + z2;
X   zd2 = zf;
X   zd1 = 1.0 - zf - zf;
X   zd0 = zf - 1.0;
X
X   /*
X    * This expressions are split up since some compilers
X    * chokes on expressions of this size.
X    */
X   v.x        = z0 * (y0 * (xd0 * p000 + xd1 * p100 + xd2 * p200) +
X                      y1 * (xd0 * p010 + xd1 * p110 + xd2 * p210) +
X                      y2 * (xd0 * p020 + xd1 * p120 + xd2 * p220));
X   v.x       += z1 * (y0 * (xd0 * p001 + xd1 * p101 + xd2 * p201) +
X                      y1 * (xd0 * p011 + xd1 * p111 + xd2 * p211) +
X                      y2 * (xd0 * p021 + xd1 * p121 + xd2 * p221));
X   v.x       += z2 * (y0 * (xd0 * p002 + xd1 * p102 + xd2 * p202) +
X                      y1 * (xd0 * p012 + xd1 * p112 + xd2 * p212) +
X                      y2 * (xd0 * p022 + xd1 * p122 + xd2 * p222));
X                                  
X   v.y        = z0 * (yd0 * (x0 * p000 + x1 * p100 + x2 * p200) +
X                      yd1 * (x0 * p010 + x1 * p110 + x2 * p210) +
X                      yd2 * (x0 * p020 + x1 * p120 + x2 * p220));
X   v.y       += z1 * (yd0 * (x0 * p001 + x1 * p101 + x2 * p201) +
X                      yd1 * (x0 * p011 + x1 * p111 + x2 * p211) +
X                      yd2 * (x0 * p021 + x1 * p121 + x2 * p221));
X   v.y       += z2 * (yd0 * (x0 * p002 + x1 * p102 + x2 * p202) +
X                      yd1 * (x0 * p012 + x1 * p112 + x2 * p212) +
X                      yd2 * (x0 * p022 + x1 * p122 + x2 * p222));
X                                  
X   v.z        = zd0 * (y0 * (x0 * p000 + x1 * p100 + x2 * p200) +
X                       y1 * (x0 * p010 + x1 * p110 + x2 * p210) +
X                       y2 * (x0 * p020 + x1 * p120 + x2 * p220));
X   v.z       += zd1 * (y0 * (x0 * p001 + x1 * p101 + x2 * p201) +
X                       y1 * (x0 * p011 + x1 * p111 + x2 * p211) +
X                       y2 * (x0 * p021 + x1 * p121 + x2 * p221));
X   v.z       += zd2 * (y0 * (x0 * p002 + x1 * p102 + x2 * p202) +
X                       y1 * (x0 * p012 + x1 * p112 + x2 * p212) +
X                       y2 * (x0 * p022 + x1 * p122 + x2 * p222));
X
X   return v;
}
X
X
X
/*
X * End of noise routines
X */
SHAR_EOF
chmod 0644 libsipp/noise.c ||
echo 'restore of libsipp/noise.c failed'
Wc_c="`wc -c < 'libsipp/noise.c'`"
test 9261 -eq "$Wc_c" ||
	echo 'libsipp/noise.c: original size 9261, current size' "$Wc_c"
fi
# ============= libsipp/noise.h ==============
if test -f 'libsipp/noise.h' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/noise.h (File already exists)'
else
echo 'x - extracting libsipp/noise.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/noise.h' &&
/*
X * Declarations needed to use noise() and friends...
X */
X
#ifndef _NOISE_H 
#define _NOISE_H 
X
X
extern void     noise_init();
extern double   noise();
extern double   turbulence();
extern Vector   Dnoise();
X
X
#endif /* _NOISE_H */
SHAR_EOF
chmod 0644 libsipp/noise.h ||
echo 'restore of libsipp/noise.h failed'
Wc_c="`wc -c < 'libsipp/noise.h'`"
test 234 -eq "$Wc_c" ||
	echo 'libsipp/noise.h: original size 234, current size' "$Wc_c"
fi
# ============= libsipp/planet.c ==============
if test -f 'libsipp/planet.c' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/planet.c (File already exists)'
else
echo 'x - extracting libsipp/planet.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/planet.c' &&
#include <stdio.h>
#include <math.h>
X
#include "sipp.h"
#include "geometric.h"
#include "noise.h"
X
X
/* A reasonably nice brown color */
static Color  land = {0.28125, 0.1875, 0.09375};
X
/* Oceans are usually blue */
static Color  sea = {0.0, 0.0, 1.0};
X
/* And Clouds are white */
static Color  cloud = {1.0, 1.0, 1.0};
X
X
/* 
X * This was designed to work with a unit sphere.  
X * 
X * Thanks to Jon Buller       jonb@vector.dallas.tx.us
X */
double
turb(size, scale_factor, loc)
X    int size;
X    double scale_factor;
X    Vector loc;
{
X    double cur_scale, result;
X    int cur;
X
X    result = noise(&loc);
X    cur_scale = 1.0;
X
X    cur = 1;
X    while (cur < size) {
X        cur <<= 1;
X        cur_scale = cur_scale * scale_factor;
X        loc.x *= 2.0;
X        loc.y *= 2.0;
X        loc.z *= 2.0;
X        result += noise(&loc) * cur_scale;
X    }
X    return result;
}
X
X
X
extern bool noise_ready;
X
void
planet_shader(nx, ny, nz, u, v, w, view_vec, lights, sd, color)
X    double        nx, ny, nz, u, v, w;
X    Vector        view_vec;
X    Lightsource  *lights;
X    Surf_desc    *sd;
X    Color        *color;
{
X    Vector  tmp;
X    double  amt;
X
X    if (!noise_ready) {
X        noise_init();
X    }
X
X    tmp.x = u;
X    tmp.y = v;
X    tmp.z = w;
X
X    if (turb(430, 0.7, tmp) > 0.15)
X        sd->color = land;
X    else 
X        sd->color = sea;
X
X    VecScalMul(tmp, 12.0, tmp)
X
X    amt = turb(18, 0.6, tmp);
X    if (amt > -0.25) {
X        amt += 0.25;
X        sd->color.red += amt * (cloud.red - sd->color.red);
X        sd->color.grn += amt * (cloud.grn - sd->color.grn);
X        sd->color.blu += amt * (cloud.blu - sd->color.blu);
X    }
X
X    basic_shader(nx, ny, nz, u, v, w, view_vec, lights, sd, color);
}
SHAR_EOF
chmod 0644 libsipp/planet.c ||
echo 'restore of libsipp/planet.c failed'
Wc_c="`wc -c < 'libsipp/planet.c'`"
test 1700 -eq "$Wc_c" ||
	echo 'libsipp/planet.c: original size 1700, current size' "$Wc_c"
fi
# ============= libsipp/primitives.h ==============
if test -f 'libsipp/primitives.h' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/primitives.h (File already exists)'
else
echo 'x - extracting libsipp/primitives.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/primitives.h' &&
extern Object *sipp_torus();
extern Object *sipp_cylinder();
extern Object *sipp_ellipsoid();
extern Object *sipp_sphere();
extern Object *sipp_block();
extern Object *sipp_cube();
extern Object *sipp_bezier();
SHAR_EOF
chmod 0644 libsipp/primitives.h ||
echo 'restore of libsipp/primitives.h failed'
Wc_c="`wc -c < 'libsipp/primitives.h'`"
test 211 -eq "$Wc_c" ||
	echo 'libsipp/primitives.h: original size 211, current size' "$Wc_c"
fi
# ============= libsipp/shaders.h ==============
if test -f 'libsipp/shaders.h' -a X"$1" != X"-c"; then
	echo 'x - skipping libsipp/shaders.h (File already exists)'
else
echo 'x - extracting libsipp/shaders.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/shaders.h' &&
/*
X * This include file defines the different shaders availiable in
X * sipp. Each shader is defined by a structure containing the necessary
X * parameters to describe how a surface should be shaded with that 
X * particular shader, and the extern declaration of the shader function 
X * itself.
X */
X
X
#ifndef _SHADERS_H
#define _SHADERS_H
X
X
#include <sipp.h>
X
X
X
/* 
X * Surface description for the bozo shader.
X */
typedef struct {
X    Color   *colors;
X    int      no_of_cols;
X    double   ambient;
X    double   specular;
X    double   c3;
X    double   scale;        /* Scale the texture by this value */
} Bozo_desc;
X    
X
X
/*
X * Surface description used by the marble shader. marble_shader
X * creates a solid texture (using noise & turbulence) that
X * simulates marble.
X */
typedef struct {
X    double   ambient;
X    double   specular;
X    double   c3;
X    double   scale;        /* Scale the marble texture by this value */
X    Color    base;         /* "Base" color of the surface */
X    Color    strip;        /* Color of the "stripes" in the marble */
} Marble_desc;
X
X
X
/*
X * Surface description used by the granite shader. granite_shader
X * creates a solid texture (using noise) that mixes two colors
X * to simulate granite.
X */
typedef struct {
X    double   ambient;
X    double   specular;
X    double   c3;
X    double   scale;        /* Scale the texture by this value */
X    Color    col1;         /* The two color components */
X    Color    col2;         /*                          */
} Granite_desc;
X
X
X
/*
X * Mask shader. This shader is SUN specific since it uses
X * a pixrect. It projects the pixrect on the x-y plane (in
X * texture coordinates). When a surface is shaded it checks
X * if the x, y coordinate in the pixrect is zero and calls
X * one of two other shaders depending of the outcome of that 
X * test.
X */
typedef struct {
X    Shader *fg_shader;          /* Shader to call if mask(x, y) != 0 */
X    void   *fg_surface;         /* Surface description for fg_shader */
X    Shader *bg_shader;          /* Shader to call if mask(x, y) == 0 */
X    void   *bg_surface;         /* Surface description for bg_shader */
X    void   *mask;               /* Pointer to mask image */
X    bool  (*pixel_test)();      /* Function that tests a pixel value */
X    int     x0, y0;             /* Where to put origo in the mask image */
X    int     xsize, ysize;       /* Size of the mask image */
X    double  xscale, yscale;     /* Scale the mask image with these values */
} Mask_desc;
X
X
/*
X * Surface description for the bumpy_shader(). This shader 
X * fiddles with the surface normals of a surface so the surface 
X * looks bumpy.
X */
X
typedef struct {
X    Shader *shader;
X    void   *surface;
X    double scale;
X    bool   bumpflag;
X    bool   holeflag;
} Bumpy_desc;
X
X
/*
X * Declarations of the actual shading functions.
X */
extern void marble_shader();
extern void granite_shader();
extern void bozo_shader();
extern void mask_shader();
extern void bumpy_shader();
extern void planet_shader();
X
#endif /* _SHADERS_H */
SHAR_EOF
chmod 0644 libsipp/shaders.h ||
echo 'restore of libsipp/shaders.h failed'
Wc_c="`wc -c < 'libsipp/shaders.h'`"
test 3024 -eq "$Wc_c" ||
	echo 'libsipp/shaders.h: original size 3024, current size' "$Wc_c"
fi
true || echo 'restore of libsipp/sipp.c failed'
echo End of part 2, continue with part 3
exit 0

-- 
Inge Wallin               | Thus spake the master programmer:               |
                          |      "After three days without programming,     |
ingwa@isy.liu.se          |       life becomes meaningless."                |
                          | Geoffrey James: The Tao of Programming.         |


exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.