/******************************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-1995 Microsoft Corporation * \**************************************************************************/ #include #include #include #include #include "ssopengl.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] = ptZero; for (facecount = 0, i = 0; i < (iPrec - 1); i++) { 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; 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.0, 1.0, -1.0, 1.0, 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(HWND hwnd, 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; float r, g, b; RGBA color; BOOL bounce; 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) { HsvToRgb((float)h, 1.0f, 1.0f, &r, &g, &b); color.r = r; color.g = g; color.b = b; 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 - r; color.g = 1.0f - g; color.b = 1.0f - 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); } bounce = vShowBuffer(hwnd); mxrot += mxrotInc; myrot += myrotInc; mzrot += mzrotInc; if (bounce) { 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; } } }