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
/
demo0.c
next >
Wrap
C/C++ Source or Header
|
1991-11-18
|
8KB
|
300 lines
/*
* testpatch.c:
*
* draws three surface patches: RED == Bezier
* BLUE == B-Spline
* GREEN == Cardinal
*/
#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
Coord geomx[4][4] = { { 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} };
Coord geomy[4][4] = { { 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} };
Coord geomz[4][4] = { { 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 } };
Coord geomxt[4][4] = { { 0.0, 0.0, 200.0, 200.0 },
{ 0.0, 0.0, 200.0, 200.0 },
{ 50.0, 50.0, 150.0, 150.0 },
{ 50.0, 50.0, 150.0, 150.0 } };
Coord geomyt[4][4] = { { 200.0, 400.0, 400.0, 200.0},
{ 200.0, 400.0, 400.0, 200.0},
{ 200.0, 350.0, 350.0, 200.0},
{ 200.0, 350.0, 350.0, 200.0} };
Coord geomzt[4][4] = { { 200.0, 200.0, 200.0, 200.0 },
{ 150.0, 150.0, 150.0, 150.0 },
{ 150.0, 150.0, 150.0, 150.0 },
{ 200.0, 200.0, 200.0, 200.0 } };
PatchPtr mypatch[3];
/*******************************************************************/
main(argc, argv)
int argc; char *argv[];
{
Device dev;
short val;
initialize();
while (TRUE) {
if (qtest()) {
dev = qread(&val);
if (dev == ESCKEY) {
gexit();
exit();
} else if (dev == REDRAW) {
reshapeviewport();
drawpatches(argc);
}
}
}
}
/*******************************************************************/
initialize(which)
int which;
{
int gid;
prefposition(XMAXSCREEN/4,XMAXSCREEN*3/4,YMAXSCREEN/4,YMAXSCREEN*3/4);
gid = winopen("patch1");
winset(gid);
winattach();
winconstraints();
qdevice(ESCKEY);
qdevice(REDRAW);
qenter(REDRAW,gid);
perspective(900, 1.0, 1.0, 10000.0 );
if (which == 1)
lookat(400.0, 400.0, 0.0, 200.0, 200.0, 250.0,0);
else
lookat(100.0, 300.0, -100.0, 200.0, 200.0, 250.0,0);
mypatch[0] = NewPatch();
mypatch[1] = NewPatch();
mypatch[2] = NewPatch();
if (which == 1) {
DefPatch(mypatch[0], beziermatrix, geomx, geomy, geomz,DIV);
DefPatch(mypatch[1], cardinalmatrix, geomx, geomy, geomz,DIV);
DefPatch(mypatch[2], bsplinematrix, geomx, geomy, geomz,DIV);
} else {
DefPatch(mypatch[0], beziermatrix, geomxt, geomyt, geomzt,DIV);
DefPatch(mypatch[1], cardinalmatrix, geomxt, geomyt, geomzt,DIV);
DefPatch(mypatch[2], bsplinematrix, geomxt, geomyt, geomzt,DIV);
}
}
/*******************************************************************/
drawpatches()
{
int i,j;
float vert[3];
for (i = 0; i < 3; i++) {
color(BLACK);
clear();
drawaxes();
color(RED);
drawpatch(mypatch[i]);
color(WHITE);
drawhull(mypatch[i]);
color(GREEN);
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();
}
}
/***************************************************************************/