VIEW.CXX

/******************************Module*Header*******************************\ 
* Module Name: view.cxx
*
* Copyright 1995 - 1998 Microsoft Corporation
*
\**************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <time.h>
#include <windows.h>

#include "sspipes.h"
#include "view.h"

/******************************Public*Routine******************************\
* VIEW constructor
\**************************************************************************/

VIEW::VIEW()
{
bProjMode = GL_TRUE;

// set some initial viewing and size params

zTrans = -75.0f;
viewDist = -zTrans;

numDiv = NUM_DIV;
SS_ASSERT( numDiv >= 2, "VIEW constructor: not enough divisions\n" );
// Because number of nodes in a dimension is derived from (numDiv-1), and
// can't be 0

divSize = 7.0f;

persp.viewAngle = 90.0f;
persp.zNear = 1.0f;

yRot = 0.0f;

winSize.width = winSize.height = 0;
}

/******************************Public*Routine******************************\
* SetProjMatrix
*
* Set GL view parameters
\**************************************************************************/

void
VIEW::SetGLView()
{
glViewport(0, 0, winSize.width, winSize.height );
SetProjMatrix();
}

/******************************Public*Routine******************************\
* SetProjMatrix
*
* Set Projection matrix
\**************************************************************************/

void
VIEW::SetProjMatrix()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

persp.zFar = viewDist + world.z*2;
if( bProjMode ) {
gluPerspective( persp.viewAngle,
aspectRatio,
persp.zNear, persp.zFar );
}
else {
glOrtho( -world.x/2, world.x/2, -world.y/2, world.y/2,
-world.z, world.z );
}
glMatrixMode(GL_MODELVIEW);
}

/******************************Public*Routine******************************\
* CalcNodeArraySize
*
* Based on the viewing width and height, and numDiv, calculate the x,y,z array
* node dimensions.
*
\**************************************************************************/

void
VIEW::CalcNodeArraySize( IPOINT3D *pNodeDim )
{
// if aspect ratio deviates too much from 1, then nodes will get
// clipped as view rotates

if( winSize.width >= winSize.height ) {
pNodeDim->x = numDiv - 1;
pNodeDim->y = (int) (pNodeDim->x / aspectRatio) ;
if( pNodeDim->y < 1 )
pNodeDim->y = 1;
pNodeDim->z = pNodeDim->x;
}
else {
pNodeDim->y = numDiv - 1;
pNodeDim->x = (int) (aspectRatio * pNodeDim->y);
if( pNodeDim->x < 1 )
pNodeDim->x = 1;
pNodeDim->z = pNodeDim->y;
}
}

/******************************Public*Routine******************************\
* SetWinSize
*
* Set the window size for the view, derive other view params.
*
* Return FALSE if new size same as old.
\**************************************************************************/

BOOL
VIEW::SetWinSize( int width, int height )
{
if( (width == winSize.width) &&
(height == winSize.height) )
return FALSE;

winSize.width = width;
winSize.height = height;

aspectRatio = winSize.height == 0 ? 1.0f : (float)winSize.width/winSize.height;

if( winSize.width >= winSize.height ) {
world.x = numDiv * divSize;
world.y = world.x / aspectRatio;
world.z = world.x;
}
else {
world.y = numDiv * divSize;
world.x = world.y * aspectRatio;
world.z = world.y;
}
return TRUE;
}

/******************************Public*Routine******************************\
* SetSceneRotation
*
\**************************************************************************/

void
VIEW::IncrementSceneRotation()
{
yRot += 9.73156f;
if( yRot >= 360.0f )
// prevent overflow
yRot -= 360.0f;
}