home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gondwana.ecr.mu.oz.au/pub/
/
Graphics.tar
/
Graphics
/
spline-patch.tar.gz
/
spline-patch.tar
/
patch
/
demos
/
demo3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-18
|
10KB
|
364 lines
/*
* File : demo3.c
* Author : Sean Graves
*
* Computer : Silicon Graphics
* Date : 6/21/90
*
* Draws the wireframe representation of a patch, using the patch.c
* routines. It then randomly shoots rays through the patch, and
* marks the intersection of the ray and the patch with a green X.
* Runs until the process is somehow killed.
*
* Copyright (c) 1990, by Sean Graves and Texas A&M University
*
* Permission is hereby granted for non-commercial reproduction and use of
* this program, provided that this notice is included in any material copied
* from it. The author assumes no responsibility for damages resulting from
* the use of this software, however caused.
*
*
*/
#include "gl.h"
#include "device.h"
#include "math.h"
#include "stdio.h"
#include "patch.h" /* My stuff */
MATRIX beziermatrix = { { -1, 3, -3, 1 },
{ 3, -6, 3, 0 },
{ -3, 3, 0, 0 },
{ 1, 0, 0, 0 } };
MATRIX cardinalmatrix = { { -0.5, 1.5, -1.5, 0.5 },
{ 1.0, -2.5, 2.0, -0.5 },
{ -0.5, 0.0, 0.5, 0.0 },
{ 0.0, 1.0, 0.0, 0.0 } };
MATRIX bsplinematrix = { { -1.0/6.0, 3.0/6.0, -3.0/6.0, 1.0/6.0 },
{ 3.0/6.0, -6.0/6.0, 3.0/6.0, 0.0 },
{ -3.0/6.0, 0.0, 3.0/6.0, 0.0 },
{ 1.0/6.0, 4.0/6.0, 1.0/6.0, 0.0 } };
#define BEZIER 1
#define CARDINAL 2
#define BSPLINE 3
#define DIV 8
MATRIX geomx = { { 0.0, 0.0, 0.0, 0.0},
{ 0.0, 100.0, 100.0, 0.0},
{ 300.0, 200.0, 200.0, 300.0},
{ 300.0, 300.0, 300.0, 300.0} };
MATRIX geomy = { { 200.0, 0.0, 200.0, 200.0},
{ 0.0, 0.0, 200.0, 0.0},
{ 0.0, 0.0, 200.0, 0.0},
{ 200.0, 0.0, 200.0, 200.0} };
MATRIX geomz = { { 100.0, 200.0, 300.0, 400.0 },
{ 100.0, 200.0, 300.0, 400.0 },
{ 100.0, 200.0, 300.0, 400.0 },
{ 100.0, 200.0, 300.0, 400.0 } };
PatchPtr mypatch[3];
/*******************************************************************/
main()
{
Device dev;
short val;
foreground();
initialize();
while (TRUE) {
if (qtest()) {
dev = qread(&val);
if (dev == ESCKEY) {
gexit();
exit();
} else if (dev == REDRAW) {
reshapeviewport();
drawpatches();
}
}
}
}
/*******************************************************************/
initialize()
{
int gid;
prefposition(XMAXSCREEN/4,XMAXSCREEN*3/4,YMAXSCREEN/4,YMAXSCREEN*3/4);
gid = winopen("testpatch");
winset(gid);
winattach();
winconstraints();
qdevice(ESCKEY);
qdevice(REDRAW);
qenter(REDRAW,gid);
perspective(900, 1.0, 1.0, 20000.0 );
lookat(400.0, 400.0, 0.0, 200.0, 200.0, 250.0,0);
mypatch[0] = NewPatch();
DefPatch(mypatch[0], beziermatrix, geomx, geomy, geomz, DIV);
mypatch[1] = NewPatch();
DefPatch(mypatch[1], cardinalmatrix, geomx, geomy, geomz, DIV);
mypatch[2] = NewPatch();
DefPatch(mypatch[2], bsplinematrix, geomx, geomy, geomz, DIV);
srand48(123);
}
/*******************************************************************/
drawpatches()
{
TreePtr tree;
int i,j;
float vert[3], mag;
RAY r;
Isectrec irec;
while (1) {
color(BLACK);
clear();
drawaxes();
color(RED);
drawpatch(mypatch[0]);
r.org.x = 150.0;
r.org.y = 400.0;
r.org.z = 200.0;
r.dir.x = (float) drand48() / 2.0;
r.dir.y = - (float) drand48();
r.dir.z = (float) drand48() / 2.0;
normalize(&(r.dir));
color(WHITE);
bgnline();
vert[0] = r.org.x ;
vert[1] = r.org.y ;
vert[2] = r.org.z ;
v3f(vert);
vert[0] = r.org.x + 400 * r.dir.x;
vert[1] = r.org.y + 400 * r.dir.y;
vert[2] = r.org.z + 400 * r.dir.z;
v3f(vert);
endline();
color(GREEN);
irec = IsectPatch(mypatch[0],r);
if (irec.t != -1.0) {
printf("Intersected at t = %f\n",irec.t);
vert[0] = irec.isect.x-8;
vert[1] = irec.isect.y;
vert[2] = irec.isect.z;
bgnline(); v3f(vert); vert[0] += 16; v3f(vert); endline();
vert[0] = irec.isect.x;
vert[1] = irec.isect.y-8;
vert[2] = irec.isect.z;
bgnline(); v3f(vert); vert[1] += 16; v3f(vert); endline();
vert[0] = irec.isect.x;
vert[1] = irec.isect.y;
vert[2] = irec.isect.z-8;
bgnline(); v3f(vert); vert[2] += 16; v3f(vert); endline();
sleep(1);
}
if (irec.t > 500) sleep(10);
}
}
/***************************************************************************/
drawaxes()
{
float vert[3];
color(RED);
bgnline(); vert[0]=0 ; vert[1]=0; vert[2]=0; v3f(vert);
vert[0]=20; vert[1]=0; vert[2]=0; v3f(vert); endline();
color(GREEN);
bgnline(); vert[0]=0; vert[1]=0 ; vert[2]=0; v3f(vert);
vert[0]=0; vert[1]=20; vert[2]=0; v3f(vert); endline();
color(BLUE);
bgnline(); vert[0]=0; vert[1]=0; vert[2]=0 ; v3f(vert);
vert[0]=0; vert[1]=0; vert[2]=20; v3f(vert); endline();
}
/***************************************************************************/
drawhull(p)
PatchPtr p;
{
int i, j;
float vert[3];
for (i = 0; i < 4; i++) {
bgnline();
for (j = 0; j <4; j++) {
vert[0] = p->geomx[j][i];
vert[1] = p->geomy[j][i];
vert[2] = p->geomz[j][i];
v3f(vert);
}
endline();
}
for (i = 0; i < 4; i++) {
bgnline();
for (j = 0; j <4; j++) {
vert[0] = p->geomx[i][j];
vert[1] = p->geomy[i][j];
vert[2] = p->geomz[i][j];
v3f(vert);
}
endline();
}
}
/**********************************************************************/
drawpatch(p)
PatchPtr p;
{
float U[1][4], V[4][1]; /* u, v vectors */
float C[4][4]; /* solution matrix (only [0][0] used) */
float M2x[4][4], M2y[4][4], M2z[4][4]; /* Intermediate results */
float u, v; /* Parameters */
float M2xdu[4][4], M2xdv[4][4]; /* Intermed. results for surface normals */
float M2ydu[4][4], M2ydv[4][4];
float M2zdu[4][4], M2zdv[4][4];
VECTOR ddu, ddv, norm;
float vert[3], vert2[3]; /* Screen vertices */
for (v = 0; v <= 1.0; v += 0.2) {
V[3][0] = 1;
V[2][0] = v;
V[1][0] = v * v;
V[0][0] = V[1][0] * v;
mmult4x4_4x1 (M2x, p->Mx, V); /* Calculate intermediate results with v */
mmult4x4_4x1 (M2y, p->My, V);
mmult4x4_4x1 (M2z, p->Mz, V);
mmult4x4_4x1 (M2xdu, p->Mxdu, V);
mmult4x4_4x1 (M2ydu, p->Mydu, V);
mmult4x4_4x1 (M2zdu, p->Mzdu, V);
mmult4x4_4x1 (M2xdv, p->Mxdv, V);
mmult4x4_4x1 (M2ydv, p->Mydv, V);
mmult4x4_4x1 (M2zdv, p->Mzdv, V);
bgnline();
for (u = 0; u <= 1.0; u += 0.02) {
U[0][3] = 1;
U[0][2] = u;
U[0][1] = u * u;
U[0][0] = U[0][1] * u;
mmult1x4_4x1 (C, U, M2x);
vert[0] = C[0][0];
mmult1x4_4x1 (C, U, M2y);
vert[1] = C[0][0];
mmult1x4_4x1 (C, U, M2z);
vert[2] = C[0][0];
v3f(vert);
if (fcmp(u,0.0) || fcmp(u, 0.2) || fcmp(u,0.4) || fcmp(u, 0.6) ||
fcmp(u, 0.8) || fcmp(u,1.0)) {
mmult1x4_4x1 (C, U, M2xdu);
ddu.x = C[0][0];
mmult1x4_4x1 (C, U, M2ydu);
ddu.y = C[0][0];
mmult1x4_4x1 (C, U, M2zdu);
ddu.z = C[0][0];
mmult1x4_4x1 (C, V, M2xdv);
ddv.x = C[0][0];
mmult1x4_4x1 (C, V, M2ydv);
ddv.y = C[0][0];
mmult1x4_4x1 (C, V, M2zdv);
ddv.z = C[0][0];
cross_product(&norm, ddu, ddv);
normalize(&norm);
vert2[0] = vert[0] + 20.0 * norm.x;
vert2[1] = vert[1] + 20.0 * norm.y;
vert2[2] = vert[2] + 20.0 * norm.z;
v3f(vert2);
v3f(vert);
}
}
endline();
}
for (u = 0; u <= 1.0; u += 0.2) {
U[0][3] = 1;
U[0][2] = u;
U[0][1] = u * u;
U[0][0] = U[0][1] * u;
mmult1x4_4x4 (M2x, U, p->Mx);
mmult1x4_4x4 (M2y, U, p->My);
mmult1x4_4x4 (M2z, U, p->Mz);
bgnline();
for (v = 0; v <= 1.0; v += 0.02) {
V[3][0] = 1;
V[2][0] = v;
V[1][0] = v * v;
V[0][0] = V[1][0] * v;
mmult1x4_4x1 (C, M2x, V);
vert[0] = C[0][0];
mmult1x4_4x1 (C, M2y, V);
vert[1] = C[0][0];
mmult1x4_4x1 (C, M2z, V);
vert[2] = C[0][0];
v3f(vert);
}
endline();
}
}
/*********************************************************************** ****/
drawbox(min, max)
POINT min, max;
{
float vert[8][3];
bgnline();
vert[0][0] = min.x; vert[0][1] = min.y; vert[0][2] = min.z;
vert[1][0] = max.x; vert[1][1] = min.y; vert[1][2] = min.z;
vert[2][0] = max.x; vert[2][1] = max.y; vert[2][2] = min.z;
vert[3][0] = min.x; vert[3][1] = max.y; vert[3][2] = min.z;
vert[4][0] = min.x; vert[4][1] = min.y; vert[4][2] = max.z;
vert[5][0] = max.x; vert[5][1] = min.y; vert[5][2] = max.z;
vert[6][0] = max.x; vert[6][1] = max.y; vert[6][2] = max.z;
vert[7][0] = min.x; vert[7][1] = max.y; vert[7][2] = max.z;
v3f(vert[0]);
v3f(vert[1]);
v3f(vert[2]);
v3f(vert[3]);
v3f(vert[0]);
v3f(vert[3]);
v3f(vert[7]);
v3f(vert[4]);
v3f(vert[0]);
v3f(vert[4]);
v3f(vert[5]);
v3f(vert[6]);
v3f(vert[7]);
v3f(vert[6]);
v3f(vert[2]);
v3f(vert[1]);
v3f(vert[5]);
endline();
}