255 lines
6.8 KiB
C
255 lines
6.8 KiB
C
|
/******************************Module*Header*******************************\
|
||
|
* Module Name: genstrip.c
|
||
|
*
|
||
|
* The Ribbon and 2 Ribbon styles of the 3D Flying Objects screen saver.
|
||
|
*
|
||
|
* Animation of 1 or 2 quad strips floating about.
|
||
|
*
|
||
|
* Copyright (c) 1994 Microsoft Corporation
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <GL\gl.h>
|
||
|
#include <string.h>
|
||
|
#include <math.h>
|
||
|
#include "ss3dfo.h"
|
||
|
#include "mesh.h"
|
||
|
|
||
|
static MESH stripMesh;
|
||
|
static int iPrec = 40;
|
||
|
|
||
|
void genStrip()
|
||
|
{
|
||
|
static int counter = 0;
|
||
|
int i;
|
||
|
int facecount;
|
||
|
// Use Hermite basis, pg 488, FVD
|
||
|
static float M[4][4] = {{2.0f, -2.0f, 1.0f, 1.0f},
|
||
|
{-3.0f, 3.0f, -2.0f, -1.0f},
|
||
|
{0.0f, 0.0f, 1.0f, 0.0f},
|
||
|
{1.0f, 0.0f, 0.0f, 0.0f}};
|
||
|
float xx[4], yy[4], zz[4];
|
||
|
float cx[4], cy[4], cz[4];
|
||
|
float d = 1.0f / (float) iPrec;
|
||
|
float t = 0.0f;
|
||
|
float t2, t3;
|
||
|
POINT3D p1 = {-0.5f, 0.0f, 0.0f};
|
||
|
POINT3D p2 = {0.5f, 0.0f, 0.0f};
|
||
|
POINT3D v1 = {1.5f, 1.5f, 0.0f};
|
||
|
POINT3D v2 = {0.0f, 3.0f, 0.0f};
|
||
|
POINT3D norm;
|
||
|
float sinVal;
|
||
|
float angle;
|
||
|
float angleStep = (float) (PI / iPrec);
|
||
|
static float rotA = 0.0f;
|
||
|
static float rotB = (float) (PI / 2.0);
|
||
|
static float sideSin = 0.0f;
|
||
|
float rotStepA = (float) (PI / (2.0 * iPrec));
|
||
|
float rotStepB = (float) (PI / (4.0 * iPrec));
|
||
|
MESH *mesh = &stripMesh;
|
||
|
|
||
|
#define NORMS(x, y) stripMesh.norms[((x) * iPrec) + y]
|
||
|
#define GRID(x, y) stripMesh.pts[((x) * iPrec) + y]
|
||
|
|
||
|
v1.x = (float) (4.0 * cos(rotA));
|
||
|
v1.y = (float) (4.0 * sin(rotA));
|
||
|
|
||
|
p2.x = (float) (0.5 * sin(rotB));
|
||
|
// p2.y = (float) (0.5 * sin(rotB));
|
||
|
|
||
|
rotA += rotStepA;
|
||
|
rotB += rotStepB;
|
||
|
counter++;
|
||
|
if (counter >= (2 * iPrec)) {
|
||
|
rotStepA = -rotStepA;
|
||
|
counter = 0;
|
||
|
}
|
||
|
|
||
|
angle = sideSin;
|
||
|
sideSin += (float) (PI / 80.0);
|
||
|
|
||
|
xx[0] = p1.x;
|
||
|
xx[1] = p2.x;
|
||
|
xx[2] = v1.x;
|
||
|
xx[3] = v2.x;
|
||
|
|
||
|
yy[0] = p1.y;
|
||
|
yy[1] = p2.y;
|
||
|
yy[2] = v1.y;
|
||
|
yy[3] = v2.y;
|
||
|
|
||
|
zz[0] = p1.z;
|
||
|
zz[1] = p2.z;
|
||
|
zz[2] = v1.z;
|
||
|
zz[3] = v2.z;
|
||
|
|
||
|
for (i = 0; i < 4; i++) {
|
||
|
cx[i] = xx[0] * M[i][0] + xx[1] * M[i][1] +
|
||
|
xx[2] * M[i][2] + xx[3] * M[i][3];
|
||
|
cy[i] = yy[0] * M[i][0] + yy[1] * M[i][1] +
|
||
|
yy[2] * M[i][2] + yy[3] * M[i][3];
|
||
|
cz[i] = zz[0] * M[i][0] + zz[1] * M[i][1] +
|
||
|
zz[2] * M[i][2] + zz[3] * M[i][3];
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < iPrec; i++) {
|
||
|
float x, y;
|
||
|
|
||
|
t += d;
|
||
|
t2 = t * t;
|
||
|
t3 = t2 * t;
|
||
|
|
||
|
x = cx[0] * t3 + cx[1] * t2 + cx[2] * t + cx[3];
|
||
|
y = cy[0] * t3 + cy[1] * t2 + cy[2] * t + cy[3];
|
||
|
|
||
|
sinVal = (float) (sin(angle) / 5.0);
|
||
|
if (sinVal < 0.0)
|
||
|
sinVal = -sinVal;
|
||
|
angle += angleStep;
|
||
|
|
||
|
GRID(0, i).x = x;
|
||
|
GRID(0, i).z = y;
|
||
|
GRID(0, i).y = 0.25f; // extrusion // + sinVal;
|
||
|
GRID(1, i).x = x;
|
||
|
GRID(1, i).z = y;
|
||
|
GRID(1, i).y = -0.25f; // - sinVal;
|
||
|
}
|
||
|
|
||
|
stripMesh.numFaces = 0;
|
||
|
|
||
|
for (i = 0; i < 2 * iPrec; i++)
|
||
|
mesh->norms[i] = ss_ptZero;
|
||
|
|
||
|
for (facecount = 0, i = 0; i < (iPrec - 1); i++) {
|
||
|
|
||
|
ss_calcNorm(&norm, &GRID(0, i + 1), &GRID(0, i), &GRID(1, i));
|
||
|
stripMesh.faces[facecount].material = 0;
|
||
|
stripMesh.faces[facecount].norm = norm;
|
||
|
|
||
|
NORMS(0, i).x += norm.x;
|
||
|
NORMS(0, i).y += norm.y;
|
||
|
NORMS(0, i).z += norm.z;
|
||
|
NORMS(1, i).x += norm.x;
|
||
|
NORMS(1, i).y += norm.y;
|
||
|
NORMS(1, i).z += norm.z;
|
||
|
|
||
|
if (i != (iPrec - 1)) {
|
||
|
NORMS(0, i+1).x += norm.x;
|
||
|
NORMS(0, i+1).y += norm.y;
|
||
|
NORMS(0, i+1).z += norm.z;
|
||
|
NORMS(1, i+1).x += norm.x;
|
||
|
NORMS(1, i+1).y += norm.y;
|
||
|
NORMS(1, i+1).z += norm.z;
|
||
|
}
|
||
|
|
||
|
stripMesh.faces[facecount].p[0] = i;
|
||
|
stripMesh.faces[facecount].p[1] = iPrec + i;
|
||
|
stripMesh.faces[facecount].p[2] = i + 1;
|
||
|
stripMesh.faces[facecount].p[3] = iPrec + i + 1;
|
||
|
stripMesh.numFaces++;
|
||
|
facecount++;
|
||
|
}
|
||
|
|
||
|
stripMesh.numPoints = 2 * iPrec;
|
||
|
|
||
|
ss_normalizeNorms(stripMesh.norms, stripMesh.numPoints);
|
||
|
}
|
||
|
|
||
|
void initStripScene()
|
||
|
{
|
||
|
iPrec = (int)(fTesselFact * 40.5);
|
||
|
if (iPrec < 4)
|
||
|
iPrec = 4;
|
||
|
|
||
|
newMesh(&stripMesh, iPrec, 2 * iPrec);
|
||
|
glMatrixMode(GL_PROJECTION);
|
||
|
glLoadIdentity();
|
||
|
glOrtho(-1.1, 1.1, -1.1, 1.1, 0.0, 3.0);
|
||
|
glTranslatef(0.0f, 0.0f, -1.5f);
|
||
|
glRotatef(50.0f, 1.0f, 0.0f, 0.0f);
|
||
|
glRotatef(50.0f, 0.0f, 1.0f, 0.0f);
|
||
|
glRotatef(12.0f, 0.0f, 0.0f, 1.0f);
|
||
|
glMatrixMode(GL_MODELVIEW);
|
||
|
}
|
||
|
|
||
|
void delStripScene()
|
||
|
{
|
||
|
delMesh(&stripMesh);
|
||
|
}
|
||
|
|
||
|
void updateStripScene(int flags)
|
||
|
{
|
||
|
static double mxrot = 0.0;
|
||
|
static double myrot = 0.0;
|
||
|
static double mzrot = 0.0;
|
||
|
static double mxrotInc = 0.0;
|
||
|
static double myrotInc = 0.1;
|
||
|
static double mzrotInc = 0.0;
|
||
|
static int h = 0;
|
||
|
RGBA color;
|
||
|
|
||
|
if( gbBounce ) {
|
||
|
// floating window bounced off an edge
|
||
|
if (mxrotInc) {
|
||
|
mxrotInc = 0.0;
|
||
|
myrotInc = 0.1;
|
||
|
} else if (myrotInc) {
|
||
|
myrotInc = 0.0;
|
||
|
mzrotInc = 0.1;
|
||
|
} else if (mzrotInc) {
|
||
|
mzrotInc = 0.0;
|
||
|
mxrotInc = 0.1;
|
||
|
}
|
||
|
gbBounce = FALSE;
|
||
|
}
|
||
|
|
||
|
glLoadIdentity();
|
||
|
glRotatef((GLfloat) (mxrot * (180.0 / PI)), 1.0f, 0.0f, 0.0f);
|
||
|
glRotatef((GLfloat) (myrot * (180.0 / PI)), 0.0f, 1.0f, 0.0f);
|
||
|
glRotatef((GLfloat) (mzrot * (180.0 / PI)), 0.0f, 0.0f, 1.0f);
|
||
|
|
||
|
genStrip();
|
||
|
|
||
|
if (bColorCycle) {
|
||
|
ss_HsvToRgb((float)h, 1.0f, 1.0f, &color );
|
||
|
|
||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
|
||
|
(GLfloat *) &color);
|
||
|
|
||
|
h++;
|
||
|
h %= 360;
|
||
|
} else {
|
||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
|
||
|
(GLfloat *) &Material[1].kd);
|
||
|
}
|
||
|
|
||
|
updateObject(&stripMesh, bSmoothShading);
|
||
|
|
||
|
if (flags & 0x4) {
|
||
|
glLoadIdentity();
|
||
|
glTranslatef(0.05f, 0.0f, 0.0f);
|
||
|
glRotatef((GLfloat) (myrot * (180.0 / PI)), 1.0f, 0.0f, 0.0f);
|
||
|
glRotatef((GLfloat) (mxrot * (180.0 / PI)), 0.0f, 1.0f, 0.0f);
|
||
|
glRotatef((GLfloat) (mzrot * (180.0 / PI)), 0.0f, 0.0f, 1.0f);
|
||
|
|
||
|
if (bColorCycle) {
|
||
|
color.r = 1.0f - color.r;
|
||
|
color.g = 1.0f - color.g;
|
||
|
color.b = 1.0f - color.b;
|
||
|
|
||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
|
||
|
(GLfloat *) &color);
|
||
|
} else {
|
||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
|
||
|
(GLfloat *) &Material[2].kd);
|
||
|
}
|
||
|
|
||
|
updateObject(&stripMesh, bSmoothShading);
|
||
|
}
|
||
|
|
||
|
mxrot += mxrotInc;
|
||
|
myrot += myrotInc;
|
||
|
mzrot += mzrotInc;
|
||
|
}
|