home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume21
/
sipp
/
part02
< prev
next >
Wrap
Text File
|
1991-07-23
|
42KB
|
1,396 lines
Newsgroups: comp.sources.misc
From: Jonas Yngvesson <jonas-y@isy.liu.se>
Subject: v21i027: sipp - A 3D rendering library v2.1, Part02/08
Message-ID: <1991Jul23.181546.27671@sparky.IMD.Sterling.COM>
X-Md4-Signature: a7e457e725d8e5318d5d31fe2378656d
Date: Tue, 23 Jul 1991 18:15:46 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: Jonas Yngvesson <jonas-y@isy.liu.se>
Posting-number: Volume 21, Issue 27
Archive-name: sipp/part02
Supersedes: sipp2.0: Volume 16, Issue 5-10
Environment: UNIX
#!/bin/sh
# This is part 02 of sipp-2.1
# ============= 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 ** sipp - SImple Polygon Processor
X **
X ** A general 3d graphic package
X **
X ** Copyright Jonas Yngvesson (jonas-y@isy.liu.se) 1988/89/90/91
X ** Inge Wallin (ingwa@isy.liu.se) 1990/91
X **
X ** This program is free software; you can redistribute it and/or modify
X ** it under the terms of the GNU General Public License as published by
X ** the Free Software Foundation; either version 1, or any later version.
X ** This program is distributed in the hope that it will be useful,
X ** but WITHOUT ANY WARRANTY; without even the implied warranty of
X ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X ** GNU General Public License for more details.
X ** You can receive a copy of the GNU General Public License from the
X ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X **/
X
/**
X ** bumpy.c - Bumpy shader: simulates an bumpy surfaces using noise and Dnoise
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 0664 libsipp/bumpy.c ||
echo 'restore of libsipp/bumpy.c failed'
Wc_c="`wc -c < 'libsipp/bumpy.c'`"
test 1894 -eq "$Wc_c" ||
echo 'libsipp/bumpy.c: original size 1894, current size' "$Wc_c"
fi
# ============= libsipp/cone.c ==============
if test -f 'libsipp/cone.c' -a X"$1" != X"-c"; then
echo 'x - skipping libsipp/cone.c (File already exists)'
else
echo 'x - extracting libsipp/cone.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/cone.c' &&
/*
X * File: sipp_cone.c
X *
X * Create a, possibly truncated, cone. Cylinder is a special case
X * of a truncated cone with the same top and bottom radius.
X *
X * Author: David Jones
X * djones@awesome.berkeley.edu
X *
X * Adapted for inclusion into the SIPP package by Jonas Yngvesson
X */
X
#include <stdio.h>
#include <math.h>
X
#include <sipp.h>
#include <xalloca.h>
X
X
Object *
sipp_cone(radius_bot, radius_top, length, res, surface, shader)
X double radius_bot;
X double radius_top;
X double length;
X int res;
X void * surface;
X Shader * shader;
{
X Object * cone;
X double * xb;
X double * yb;
X double * xt;
X double * yt;
X double frac;
X double half_length;
X int bot_exists;
X int top_exists;
X int i;
X
X /*
X * If both top and bottom radii is zero it's a line
X * and can't be rendered.
X */
X if (radius_bot == 0.0 && radius_top == 0.0) {
X return NULL;
X }
X
X if (radius_bot > 0.0) {
X xb = (double *) alloca((res + 1) * sizeof(double));
X yb = (double *) alloca((res + 1) * sizeof(double));
X bot_exists = 1;
X } else if (radius_bot == 0.0 ){
X bot_exists = 0;
X } else {
X return NULL;
X }
X
X if (radius_top > 0.0) {
X xt = (double *) alloca((res + 1) * sizeof(double));
X yt = (double *) alloca((res + 1) * sizeof(double));
X top_exists = 1;
X } else if (radius_top == 0.0) {
X top_exists = 0;
X } else {
X return NULL;
X }
X
X /* list of coordinates */
X for (i = 0; i <= res ; ++i) {
X frac = ((double) i) / ((double) res);
X if (bot_exists) {
X xb[i] = radius_bot * cos(frac * 2.0 * M_PI);
X yb[i] = radius_bot * sin(frac * 2.0 * M_PI);
X }
X if (top_exists) {
X xt[i] = radius_top * cos(frac * 2.0 * M_PI);
X yt[i] = radius_top * sin(frac * 2.0 * M_PI);
X }
X }
X
X half_length = length * 0.5;
X
X /* empty object */
X cone = object_create();
X
X /* The bottom surface */
X if (bot_exists) {
X for (i = res - 1; i >= 0 ; --i) {
X vertex_tx_push(xb[i], yb[i], -half_length,
X xb[i], yb[i], -half_length);
X }
X polygon_push();
X object_add_surface(cone, surface_create(surface, shader));
X }
X
X /* The top surface */
X if (top_exists) {
X for (i = 0; i < res ; ++i) {
X vertex_tx_push(xt[i], yt[i], half_length,
X xt[i], yt[i], half_length);
X }
X polygon_push();
X object_add_surface(cone, surface_create(surface, shader));
X }
X
X /* The side surface */
X for (i = 0; i < res ; ++i) {
X if (top_exists && bot_exists) {
X vertex_tx_push(xb[i], yb[i], -half_length,
X xb[i], yb[i], -half_length);
X vertex_tx_push(xb[i+1], yb[i+1], -half_length,
X xb[i+1], yb[i+1], -half_length);
X vertex_tx_push(xt[i+1], yt[i+1], half_length,
X xt[i+1], yt[i+1], half_length);
X vertex_tx_push(xt[i], yt[i], half_length,
X xt[i], yt[i], half_length);
X } else if (top_exists) {
X vertex_tx_push(0.0, 0.0, -half_length,
X 0.0, 0.0, -half_length);
X vertex_tx_push(xt[i+1], yt[i+1], half_length,
X xt[i+1], yt[i+1], half_length);
X vertex_tx_push(xt[i], yt[i], half_length,
X xt[i], yt[i], half_length);
X } else {
X vertex_tx_push(xb[i], yb[i], -half_length,
X xb[i], yb[i], -half_length);
X vertex_tx_push(xb[i+1], yb[i+1], -half_length,
X xb[i+1], yb[i+1], -half_length);
X vertex_tx_push(0.0, 0.0, half_length,
X 0.0, 0.0, half_length);
X }
X polygon_push();
X }
X object_add_surface(cone, surface_create(surface, shader));
X
X return cone;
}
X
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
X cylinder = sipp_cone(radius, radius, length, res, surface, shader);
X
X return cylinder;
}
SHAR_EOF
chmod 0664 libsipp/cone.c ||
echo 'restore of libsipp/cone.c failed'
Wc_c="`wc -c < 'libsipp/cone.c'`"
test 4352 -eq "$Wc_c" ||
echo 'libsipp/cone.c: original size 4352, 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' &&
/**
X ** sipp - SImple Polygon Processor
X **
X ** A general 3d graphic package
X **
X ** Copyright Jonas Yngvesson (jonas-y@isy.liu.se) 1988/89/90/91
X ** Inge Wallin (ingwa@isy.liu.se) 1990/91
X **
X ** This program is free software; you can redistribute it and/or modify
X ** it under the terms of the GNU General Public License as published by
X ** the Free Software Foundation; either version 1, or any later version.
X ** This program is distributed in the hope that it will be useful,
X ** but WITHOUT ANY WARRANTY; without even the implied warranty of
X ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X ** GNU General Public License for more details.
X ** You can receive a copy of the GNU General Public License from the
X ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X **/
X
/**
X ** ellipsoid.c - Creating ellipsiods and spheres as sipp objects.
X **/
X
#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 0664 libsipp/ellipsoid.c ||
echo 'restore of libsipp/ellipsoid.c failed'
Wc_c="`wc -c < 'libsipp/ellipsoid.c'`"
test 4769 -eq "$Wc_c" ||
echo 'libsipp/ellipsoid.c: original size 4769, 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 ** sipp - SImple Polygon Processor
X **
X ** A general 3d graphic package
X **
X ** Copyright Jonas Yngvesson (jonas-y@isy.liu.se) 1988/89/90/91
X ** Inge Wallin (ingwa@isy.liu.se) 1990/91
X **
X ** This program is free software; you can redistribute it and/or modify
X ** it under the terms of the GNU General Public License as published by
X ** the Free Software Foundation; either version 1, or any later version.
X ** This program is distributed in the hope that it will be useful,
X ** but WITHOUT ANY WARRANTY; without even the implied warranty of
X ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X ** GNU General Public License for more details.
X ** You can receive a copy of the GNU General Public License from the
X ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X **/
X
/**
X ** geometric.c - Matrixes, transformations and coordinates.
X **/
X
#include <stdio.h>
#include <math.h>
X
#include <sipp.h>
#include <geometric.h>
X
X
/* =================================================================== */
X /* */
X
X
Transf_mat ident_matrix = {{ /* Unit tranfs. matrix */
X { 1.0, 0.0, 0.0 },
X { 0.0, 1.0, 0.0 },
X { 0.0, 0.0, 1.0 },
X { 0.0, 0.0, 0.0 }
}};
X
X
/* =================================================================== */
X
/*
X * Allocate a new matrix, and if INITMAT != NULL copy the contents
X * of INITMAT to the new matrix, otherwise copy the identity matrix
X * to the new matrix.
X */
X
Transf_mat *
transf_mat_create(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 else
X MatCopy(mat, &ident_matrix);
X
X return mat;
}
X
X
void
transf_mat_destruct(mat)
X Transf_mat * mat;
{
X free(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 described by DX, DY and DZ.
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 if (fabs(cosang) < 1.0e-15) {
X cosang = 0.0;
X }
X if (fabs(sinang) < 1.0e-15) {
X sinang = 0.0;
X }
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 if (fabs(cosang) < 1.0e-15) {
X cosang = 0.0;
X }
X if (fabs(sinang) < 1.0e-15) {
X sinang = 0.0;
X }
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 if (fabs(cosang) < 1.0e-15) {
X cosang = 0.0;
X }
X if (fabs(sinang) < 1.0e-15) {
X sinang = 0.0;
X }
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_y(mat, ang3);
X mat_rotate_z(mat, ang2);
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 XSCALE, YSCALE and ZSCALE
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 NORM.
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];
}
SHAR_EOF
chmod 0664 libsipp/geometric.c ||
echo 'restore of libsipp/geometric.c failed'
Wc_c="`wc -c < 'libsipp/geometric.c'`"
test 10785 -eq "$Wc_c" ||
echo 'libsipp/geometric.c: original size 10785, 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 ** sipp - SImple Polygon Processor
X **
X ** A general 3d graphic package
X **
X ** Copyright Jonas Yngvesson (jonas-y@isy.liu.se) 1988/89/90/91
X ** Inge Wallin (ingwa@isy.liu.se) 1990/91
X **
X ** This program is free software; you can redistribute it and/or modify
X ** it under the terms of the GNU General Public License as published by
X ** the Free Software Foundation; either version 1, or any later version.
X ** This program is distributed in the hope that it will be useful,
X ** but WITHOUT ANY WARRANTY; without even the implied warranty of
X ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X ** GNU General Public License for more details.
X ** You can receive a copy of the GNU General Public License from the
X ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X **/
X
/**
X ** geometric.h - All kinds of stuff with matrixes, transformations,
X ** coordinates
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
typedef struct {
X double x, y, z;
} Vector;
X
X
/*
X * NOTE:
X * Capitalized types denote Vectors and other aggregates.
X * Lower case denote scalars.
X */
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
/*
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
typedef struct {
X double mat[4][3];
} Transf_mat;
X
X
extern Transf_mat ident_matrix;
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 * transf_mat_create(/* 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 *, Vector *, Vector *, double */);
extern void mat_scale(/* Matrix *, double, double, double */);
extern void mat_mirror_plane(/* Matrix *, Vector *, Vector * */);
extern void mat_mul(/* Matrix *, Matrix *, Matrix * */);
extern void point_transform(/* Vector *, Vector *, Matrix * */);
X
X
#endif /* _GEOMETRIC_H_ */
SHAR_EOF
chmod 0664 libsipp/geometric.h ||
echo 'restore of libsipp/geometric.h failed'
Wc_c="`wc -c < 'libsipp/geometric.h'`"
test 4676 -eq "$Wc_c" ||
echo 'libsipp/geometric.h: original size 4676, 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 ** sipp - SImple Polygon Processor
X **
X ** A general 3d graphic package
X **
X ** Copyright Jonas Yngvesson (jonas-y@isy.liu.se) 1988/89/90/91
X ** Inge Wallin (ingwa@isy.liu.se) 1990/91
X **
X ** This program is free software; you can redistribute it and/or modify
X ** it under the terms of the GNU General Public License as published by
X ** the Free Software Foundation; either version 1, or any later version.
X ** This program is distributed in the hope that it will be useful,
X ** but WITHOUT ANY WARRANTY; without even the implied warranty of
X ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X ** GNU General Public License for more details.
X ** You can receive a copy of the GNU General Public License from the
X ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X **/
X
/**
X ** granite.c - Granite shader: using a 1/f fractal noise function for
X ** mixing 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 2260 -eq "$Wc_c" ||
echo 'libsipp/granite.c: original size 2260, current size' "$Wc_c"
fi
# ============= libsipp/lightsource.c ==============
if test -f 'libsipp/lightsource.c' -a X"$1" != X"-c"; then
echo 'x - skipping libsipp/lightsource.c (File already exists)'
else
echo 'x - extracting libsipp/lightsource.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/lightsource.c' &&
/**
X ** sipp - SImple Polygon Processor
X **
X ** A general 3d graphic package
X **
X ** Copyright Jonas Yngvesson (jonas-y@isy.liu.se) 1988/89/90/91
X ** Inge Wallin (ingwa@isy.liu.se) 1990/91
X **
X ** This program is free software; you can redistribute it and/or modify
X ** it under the terms of the GNU General Public License as published by
X ** the Free Software Foundation; either version 1, or any later version.
X ** This program is distributed in the hope that it will be useful,
X ** but WITHOUT ANY WARRANTY; without even the implied warranty of
X ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X ** GNU General Public License for more details.
X ** You can receive a copy of the GNU General Public License from the
X ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X **/
X
/**
X ** lightsource.c - Functions that handles lightsources.
X **/
X
#include <geometric.h>
#include <lightsource.h>
#include <sipp.h>
#include <smalloc.h>
X
X
Lightsource *lightsrc_stack; /* Stack of installed lightsources. */
X
X
/*
X * Define a new lightsource in the scene.
X */
void
lightsource_push(x, y, z, intensity)
X double x, y, z, intensity;
{
X double norm;
X Lightsource *lp;
X
X norm = sqrt(x * x + y * y + z * z);
X lp = (Lightsource *)smalloc(sizeof(Lightsource));
X lp->dir.x = x / norm;
X lp->dir.y = y / norm;
X lp->dir.z = z / norm;
X lp->intensity = intensity;
X lp->next = lightsrc_stack;
X lightsrc_stack = lp;
}
X
X
SHAR_EOF
chmod 0644 libsipp/lightsource.c ||
echo 'restore of libsipp/lightsource.c failed'
Wc_c="`wc -c < 'libsipp/lightsource.c'`"
test 1503 -eq "$Wc_c" ||
echo 'libsipp/lightsource.c: original size 1503, current size' "$Wc_c"
fi
# ============= libsipp/lightsource.h ==============
if test -f 'libsipp/lightsource.h' -a X"$1" != X"-c"; then
echo 'x - skipping libsipp/lightsource.h (File already exists)'
else
echo 'x - extracting libsipp/lightsource.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'libsipp/lightsource.h' &&
/**
X ** sipp - SImple Polygon Processor
X **
X ** A general 3d graphic package
X **
X ** Copyright Jonas Yngvesson (jonas-y@isy.liu.se) 1988/89/90/91
X ** Inge Wallin (ingwa@isy.liu.se) 1990/91
X **
X ** This program is free software; you can redistribute it and/or modify
X ** it under the terms of the GNU General Public License as published by
X ** the Free Software Foundation; either version 1, or any later version.
X ** This program is distributed in the hope that it will be useful,
X ** but WITHOUT ANY WARRANTY; without even the implied warranty of
X ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X ** GNU General Public License for more details.
X ** You can receive a copy of the GNU General Public License from the
X ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X **/
X
/**
X ** lightsource.h - Interface to lightsource.c
X **/
X
#ifndef LIGHTSOURCE_H
#define LIGHTSOURCE_H
X
#include <sipp.h>
X
X
extern Lightsource *lightsrc_stack; /* Lightsource list. */
X
X
#define lightsource_init() lightsrc_stack = NULL
X
X
#endif /* LIGHTSOURCE_H */
SHAR_EOF
chmod 0644 libsipp/lightsource.h ||
echo 'restore of libsipp/lightsource.h failed'
Wc_c="`wc -c < 'libsipp/lightsource.h'`"
test 1109 -eq "$Wc_c" ||
echo 'libsipp/lightsource.h: original size 1109, 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 ** sipp - SImple Polygon Processor
X **
X ** A general 3d graphic package
X **
X ** Copyright Jonas Yngvesson (jonas-y@isy.liu.se) 1988/89/90/91
X ** Inge Wallin (ingwa@isy.liu.se) 1990/91
X **
X ** This program is free software; you can redistribute it and/or modify
X ** it under the terms of the GNU General Public License as published by
X ** the Free Software Foundation; either version 1, or any later version.
X ** This program is distributed in the hope that it will be useful,
X ** but WITHOUT ANY WARRANTY; without even the implied warranty of
X ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X ** GNU General Public License for more details.
X ** You can receive a copy of the GNU General Public License from the
X ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X **/
X
/**
X ** marble.c - 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, 7) * 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 0664 libsipp/marble.c ||
echo 'restore of libsipp/marble.c failed'
Wc_c="`wc -c < 'libsipp/marble.c'`"
test 2442 -eq "$Wc_c" ||
echo 'libsipp/marble.c: original size 2442, 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' &&
/**
X ** sipp - SImple Polygon Processor
X **
X ** A general 3d graphic package
X **
X ** Copyright Jonas Yngvesson (jonas-y@isy.liu.se) 1988/89/90/91
X ** Inge Wallin (ingwa@isy.liu.se) 1990/91
X **
X ** This program is free software; you can redistribute it and/or modify
X ** it under the terms of the GNU General Public License as published by
X ** the Free Software Foundation; either version 1, or any later version.
X ** This program is distributed in the hope that it will be useful,
X ** but WITHOUT ANY WARRANTY; without even the implied warranty of
X ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X ** GNU General Public License for more details.
X ** You can receive a copy of the GNU General Public License from the
X ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X **/
X
/**
X ** mask.c - Mask shader: use a masking function to select between
X ** two shaders.
X **/
X
#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 0664 libsipp/mask.c ||
echo 'restore of libsipp/mask.c failed'
Wc_c="`wc -c < 'libsipp/mask.c'`"
test 1687 -eq "$Wc_c" ||
echo 'libsipp/mask.c: original size 1687, current size' "$Wc_c"
fi
true || echo 'restore of libsipp/noise.c failed'
echo End of part 2, continue with part 3
exit 0
--
------------------------------------------------------------------------------
J o n a s Y n g v e s s o n
Dept. of Electrical Engineering jonas-y@isy.liu.se
University of Linkoping, Sweden ...!uunet!isy.liu.se!jonas-y
exit 0 # Just in case...