/******************************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 #include #include #include "D3DSaver.h" #include "FlyingObjects.h" #include "mesh.h" static MESH stripMesh; static int iPrec = 40; void genStrip(FLOAT fTimeFactor) { 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)) * fTimeFactor; float rotStepB = (float) (PI / (4.0 * iPrec)) * fTimeFactor; 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); } BOOL initStripScene() { iPrec = (int)(fTesselFact * 40.5); if (iPrec < 4) iPrec = 4; if( !newMesh(&stripMesh, iPrec, 2 * iPrec) ) return FALSE; /* D3DXMATRIX matProj; D3DXMatrixOrthoLH( &matProj, 2.2f, 2.2f, 0.0f, 3.0f ); m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); */ SetProjectionMatrixInfo( TRUE, 2.2f, 2.2f, 0.0f, 3.0f ); D3DXMATRIX mat1, mat2, mat3, mat4, matFinal; D3DXMatrixTranslation(&mat1, 0.0f, 0.0f, 1.5f); D3DXMatrixRotationX(&mat2, D3DXToRadian(50.0f)); D3DXMatrixRotationY(&mat3, D3DXToRadian(50.0f)); D3DXMatrixRotationZ(&mat4, D3DXToRadian(12.0f)); matFinal = mat4 * mat3 * mat2 * mat1 ; m_pd3dDevice->SetTransform( D3DTS_VIEW, &matFinal ); // m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); return TRUE; } void delStripScene() { delMesh(&stripMesh); } void updateStripScene(int flags, FLOAT fElapsedTime) { 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 FLOAT fH = 0.0f; if( fElapsedTime > 0.25f ) fElapsedTime = 0.25f; FLOAT fTimeFactor = fElapsedTime * 20.0f; RGBA color; D3DXMATRIX mat1, mat2, mat3, mat4, mat5, matFinal; // This is to deal with when you set maximum size and // gbBounce is TRUE every frame. If that's happening, // don't toggle the rotInc's or the scene will jiggle. static BOOL bBounceLast = FALSE; if( gbBounce ) { if( bBounceLast ) { } else { // 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; bBounceLast = TRUE; } else { bBounceLast = FALSE; } D3DXMatrixRotationX(&mat1, D3DXToRadian((FLOAT)(mxrot * (180.0 / PI)))); D3DXMatrixRotationY(&mat2, D3DXToRadian((FLOAT)(myrot * (180.0 / PI)))); D3DXMatrixRotationZ(&mat3, D3DXToRadian((FLOAT)(mzrot * (180.0 / PI)))); matFinal = mat3 * mat2 * mat1 ; m_pd3dDevice->SetTransform( D3DTS_WORLD, &matFinal ); genStrip(fTimeFactor); if (bColorCycle) { ss_HsvToRgb(fH, 1.0f, 1.0f, &color ); myglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (FLOAT *) &color); fH += fTimeFactor; if( fH >= 360.0f ) fH -= 360.0f; } else { myglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (FLOAT *) &Material[1].Diffuse); } RenderMesh3(&stripMesh, bSmoothShading); RenderMesh3Backsides(&stripMesh, bSmoothShading); if (flags & 0x4) { D3DXMatrixTranslation(&mat1, 0.05f, 0.0f, 0.0f); D3DXMatrixRotationX(&mat2, D3DXToRadian((FLOAT)(myrot * (180.0 / PI)))); D3DXMatrixRotationY(&mat3, D3DXToRadian((FLOAT)(mxrot * (180.0 / PI)))); D3DXMatrixRotationZ(&mat4, D3DXToRadian((FLOAT)(mzrot * (180.0 / PI)))); matFinal = mat4 * mat3 * mat2 * mat1 ; m_pd3dDevice->SetTransform( D3DTS_WORLD , &matFinal ); if (bColorCycle) { color.r = 1.0f - color.r; color.g = 1.0f - color.g; color.b = 1.0f - color.b; myglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (FLOAT *) &color); } else { myglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (FLOAT *) &Material[2].Diffuse); } RenderMesh3(&stripMesh, bSmoothShading); RenderMesh3Backsides(&stripMesh, bSmoothShading); } mxrot += mxrotInc * fTimeFactor; myrot += myrotInc * fTimeFactor; mzrot += mzrotInc * fTimeFactor; }