www.pudn.com > 3dsMFCRender.rar > TriObject.cpp, change:1998-05-23,size:21172b
//////////////////////////////////////////////////////////////////////
//
// TriObject.cpp: implementation of the TriObject class.
// TriObject class version 1.5
// (C) 1998 - Sivert L. Nielsen (sivni@qeocities.com)
// This code may be freely distributed and used in programs so long
// as this notice appears in the code.
//
// One world, one mind.
//
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
//#include "3ds.h"
#include "TriObject.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
TriObject::TriObject()
{
x = y = z = nx = ny = nz = NULL;
matfaces = faces = NULL;
materials = NULL;
poskeys = NULL;
rotkeys = NULL;
sclkeys = NULL;
splrotmover = NULL;
splposmover = NULL;
numvertices = 0;
numnormals = 0;
numfaces = 0;
nummatfacesapplied = 0;
i = 0;
nummaterials=0;
numposkeys=0;
numrotkeys=0;
numsclkeys=0;
animstart=0;
animend=0;
currentframe=0;
currentkeypostime=0;
currentkeyrottime=0;
currentkeyscltime=0;
numsplrotkeys = 0;
numsplposkeys = 0;
offset[0] = 0.0f;
offset[1] = 0.0f;
offset[2] = 0.0f;
pivot[0] = 0.0f;
pivot[1] = 0.0f;
pivot[2] = 0.0f;
pivotrot[0] = 0.0f;
pivotrot[1] = 0.0f;
pivotrot[2] = 0.0f;
pivotrot[3] = 0.0f;
normalapplied = FALSE;
bboxapplied = FALSE;
materialsapplied = FALSE;
poskeysapplied = FALSE;
rotkeysapplied = FALSE;
sclkeysapplied = FALSE;
displistapplied = FALSE;
splinesapplied = FALSE;
}
TriObject::~TriObject()
{
delete [] x;
delete [] y;
delete [] z;
delete [] nx;
delete [] ny;
delete [] nz;
delete [] faces;
delete [] matfaces;
delete [] materials;
delete [] poskeys;
delete [] rotkeys;
delete [] sclkeys;
delete splrotmover;
}
void TriObject::applyNormals()
{
if (numfaces == 0) return;
delete [] nx;
delete [] ny;
delete [] nz;
nx = new float[numfaces/3];
ny = new float[numfaces/3];
nz = new float[numfaces/3];
if( nx==NULL || ny==NULL || nz==NULL )
{
delete [] nx;
delete [] ny;
delete [] nz;
normalapplied = FALSE;
return;
}
float normal[3];
for ( int i=0 ; i<numfaces/3 ; i++ ) //get to work
{
CalcNormal(3*i, normal);
ReduceToUnit(normal);
nx[i] = normal[0];
ny[i] = normal[1];
nz[i] = normal[2];
}
normalapplied = TRUE;
}
void TriObject::CalcNormal(int entry, float out [ 3 ])
{
float v1[3],v2[3];
// Calculate two vectors from the three points
v1[0] = x[ faces[entry] ] - x[ faces[entry+1] ];
v1[1] = y[ faces[entry] ] - y[ faces[entry+1] ];
v1[2] = z[ faces[entry] ] - z[ faces[entry+1] ];
v2[0] = x[ faces[entry+1] ] - x[ faces[entry+2] ];
v2[1] = y[ faces[entry+1] ] - y[ faces[entry+2] ];
v2[2] = z[ faces[entry+1] ] - z[ faces[entry+2] ];
// Take the cross product of the two vectors to get
// the normal vector which will be stored in out
out[0] = v1[1]*v2[2] - v1[2]*v2[1];
out[1] = v1[2]*v2[0] - v1[0]*v2[2];
out[2] = v1[0]*v2[1] - v1[1]*v2[0];
}
void TriObject::ReduceToUnit(float vector [ 3 ])
{
float length;
// Calculate the length of the vector
length = (float)sqrt((vector[0]*vector[0]) +
(vector[1]*vector[1]) +
(vector[2]*vector[2]));
// Keep the program from blowing up by providing an exceptable
// value for vectors that may calculated too close to zero.
if(length == 0.0f)
length = 1.0f;
// Dividing each element by the length will result in a
// unit normal vector.
vector[0] /= length;
vector[1] /= length;
vector[2] /= length;
}
void TriObject::drawGL()
{
value = currentframe *numsplrotkeys / (float)animend;
valuepos = currentframe *numsplposkeys / (float)animend;
if(poskeysapplied)
{
::glPushMatrix();
if(rotkeysapplied)
{
if(splinesapplied)
{
::glTranslatef(offset[0] + splposmover->GetValueAtTime(0, valuepos), offset[1] + splposmover->GetValueAtTime(1, valuepos), offset[2] + splposmover->GetValueAtTime(2, valuepos) );
::glRotatef( splrotmover->GetValueAtTime(3, value), splrotmover->GetValueAtTime(0, value), splrotmover->GetValueAtTime(1, value), splrotmover->GetValueAtTime(2, value) );
}
else
{
::glTranslatef(pivot[0]+poskeys[currentkeypostime].pos[0], pivot[1]+poskeys[currentkeypostime].pos[1], pivot[2]+poskeys[currentkeypostime].pos[2]);
::glRotatef( rotkeys[currentkeyrottime].angle, rotkeys[currentkeyrottime].axis[0], rotkeys[currentkeyrottime].axis[1], rotkeys[currentkeyrottime].axis[2] );
}
::glTranslatef(pivot[0],pivot[1],pivot[2]);
}
}
if (normalapplied)
{
int j;
glBegin(GL_TRIANGLES);
for (i=0; i <numfaces/3; i++)
{
j = 3*i;
if(materialsapplied) glColor4f( materials[matfaces[i]].diffuseColor[0], materials[matfaces[i]].diffuseColor[1], materials[matfaces[i]].diffuseColor[2], 1/materials[matfaces[i]].transparency );
else glColor3f( 0.0f, 0.0f, 1.0f );
::glNormal3f( nx[i], ny[i], nz[i]);
::glVertex3f( x[faces[j]] , y[faces[j]] , z[faces[j]]);
::glVertex3f( x[faces[j+1]], y[faces[j+1]], z[faces[j+1]]);
::glVertex3f( x[faces[j+2]], y[faces[j+2]], z[faces[j+2]]);
}
glEnd();
}
else
{
glBegin(GL_TRIANGLES);
for (i=0; i <numfaces; i+=3)
{
if(materialsapplied) glColor3f( materials[matfaces[i/3]].diffuseColor[0], materials[matfaces[i/3]].diffuseColor[1], materials[matfaces[i/3]].diffuseColor[2] );
else glColor3f( 0.0f, 0.0f, 1.0f );
glVertex3f( x[faces[i]] , y[faces[i]] , z[faces[i]]);
glVertex3f( x[faces[i+1]], y[faces[i+1]], z[faces[i+1]]);
glVertex3f( x[faces[i+2]], y[faces[i+2]], z[faces[i+2]]);
}
glEnd();
}
if(poskeysapplied) ;glPopMatrix();
}
void TriObject::drawGLBbox()
{
value = currentframe *numsplrotkeys / (float)animend;
valuepos = currentframe *numsplposkeys / (float)animend;
if(bboxapplied)
{
if(poskeysapplied)
{
::glPushMatrix();
if(rotkeysapplied)
{
if(splinesapplied)
{
::glTranslatef(pivot[0] + splposmover->GetValueAtTime(0, valuepos), pivot[1] + splposmover->GetValueAtTime(1, valuepos), pivot[2] + splposmover->GetValueAtTime(2, valuepos) );
::glRotatef( splrotmover->GetValueAtTime(3, value), splrotmover->GetValueAtTime(0, value), splrotmover->GetValueAtTime(1, value), splrotmover->GetValueAtTime(2, value) );
}
else
{
::glTranslatef(pivot[0]+poskeys[currentkeypostime].pos[0], pivot[1]+poskeys[currentkeypostime].pos[1], pivot[2]+poskeys[currentkeypostime].pos[2]);
::glRotatef( rotkeys[currentkeyrottime].angle, rotkeys[currentkeyrottime].axis[0], rotkeys[currentkeyrottime].axis[1], rotkeys[currentkeyrottime].axis[2] );
}
::glTranslatef(pivot[0],pivot[1],pivot[2]);
}
}
if(materialsapplied) glColor3f( materials[matfaces[0]].diffuseColor[0], materials[matfaces[0]].diffuseColor[1], materials[matfaces[0]].diffuseColor[2] );
else glColor3f( 0.0f, 0.0f, 1.0f );
glBegin(GL_TRIANGLES);
glNormal3f(1.0f,0.0f, 0.0f);
glVertex3fv( bbox[5]);
glVertex3fv( bbox[0]);
glVertex3fv( bbox[1]);
glVertex3fv( bbox[1]);
glVertex3fv( bbox[6]);
glVertex3fv( bbox[5]);
glNormal3f(-1.0f,0.0f, 0.0f);
glVertex3fv( bbox[2]);
glVertex3fv( bbox[3]);
glVertex3fv( bbox[4]);
glVertex3fv( bbox[4]);
glVertex3fv( bbox[7]);
glVertex3fv( bbox[2]);
glNormal3f(0.0f,0.0f, 1.0f);
glVertex3fv( bbox[4]);
glVertex3fv( bbox[3]);
glVertex3fv( bbox[0]);
glVertex3fv( bbox[0]);
glVertex3fv( bbox[5]);
glVertex3fv( bbox[4]);
glNormal3f(0.0f,0.0f, -1.0f);
glVertex3fv( bbox[6]);
glVertex3fv( bbox[1]);
glVertex3fv( bbox[2]);
glVertex3fv( bbox[2]);
glVertex3fv( bbox[7]);
glVertex3fv( bbox[6]);
glNormal3f(0.0f,-1.0f, 0.0f);
glVertex3fv( bbox[1]);
glVertex3fv( bbox[0]);
glVertex3fv( bbox[3]);
glVertex3fv( bbox[3]);
glVertex3fv( bbox[2]);
glVertex3fv( bbox[1]);
glNormal3f(0.0f,1.0f, 0.0f);
glVertex3fv( bbox[6]);
glVertex3fv( bbox[7]);
glVertex3fv( bbox[4]);
glVertex3fv( bbox[4]);
glVertex3fv( bbox[5]);
glVertex3fv( bbox[6]);
glEnd();
if(poskeysapplied) glPopMatrix();
}
}
BOOL TriObject::isDataAlive()
{
return ( x != NULL && y != NULL && z != NULL );
}
void TriObject::applyBbox()
{
if (isDataAlive())
{
float minx=x[0], maxx=x[0], miny=y[0], maxy=y[0], minz=z[0], maxz = z[0];
for( int i=1; i<numvertices; i++)
{
minx = (x[i] minx) ? x[i] : minx;
maxx = (x[i] > maxx) ? x[i] : maxx;
miny = (y[i] miny) ? y[i] : miny;
maxy = (y[i] > maxy) ? y[i] : maxy;
minz = (z[i] minz) ? z[i] : minz;
maxz = (z[i] > maxz) ? z[i] : maxz;
}
bbox[0][0] = maxx;
bbox[1][0] = maxx;
bbox[5][0] = maxx;
bbox[6][0] = maxx;
bbox[2][0] = minx;
bbox[3][0] = minx;
bbox[4][0] = minx;
bbox[7][0] = minx;
bbox[4][1] = maxy;
bbox[5][1] = maxy;
bbox[6][1] = maxy;
bbox[7][1] = maxy;
bbox[0][1] = miny;
bbox[1][1] = miny;
bbox[2][1] = miny;
bbox[3][1] = miny;
bbox[0][2] = maxz;
bbox[3][2] = maxz;
bbox[4][2] = maxz;
bbox[5][2] = maxz;
bbox[1][2] = minz;
bbox[2][2] = minz;
bbox[6][2] = minz;
bbox[7][2] = minz; //....phew!..
offset[0] = (maxx - minx)/2 + minx ;
offset[1] = (maxy - miny)/2 + miny;
offset[2] = (maxz - minz)/2 + minz;
bboxapplied = TRUE;
}
else
{
bboxapplied = FALSE;
}
}
int TriObject::addMaterial(tMaterial * _material)
{
tMaterial * tmp;
nummaterials++;
if (nummaterials==1)
{
materials = new tMaterial[nummaterials];
if (materials == NULL)
{
nummaterials = 0;
materialsapplied = FALSE;
return -1;
}
}
else
{
tmp = materials;
materials = new tMaterial[nummaterials];
if (materials == NULL)
{
delete [] tmp;
nummaterials = 0;
materialsapplied = FALSE;
return -1;
}
for (i=0; i<nummaterials-1;i++)
{
materials[i] = tmp[i]; //Copy existing materials into the newly created array
}
}
//Insert the new material last in the array
materials[nummaterials-1].ambientColor[0] = _material->ambientColor[0];
materials[nummaterials-1].ambientColor[1] = _material->ambientColor[1];
materials[nummaterials-1].ambientColor[2] = _material->ambientColor[2];
materials[nummaterials-1].diffuseColor[0] = _material->diffuseColor[0];
materials[nummaterials-1].diffuseColor[1] = _material->diffuseColor[1];
materials[nummaterials-1].diffuseColor[2] = _material->diffuseColor[2];
materials[nummaterials-1].specularColor[0] = _material->specularColor[0];
materials[nummaterials-1].specularColor[1] = _material->specularColor[1];
materials[nummaterials-1].specularColor[2] = _material->specularColor[2];
materials[nummaterials-1].emissiveColor[0] = _material->emissiveColor[0];
materials[nummaterials-1].emissiveColor[1] = _material->emissiveColor[1];
materials[nummaterials-1].emissiveColor[2] = _material->emissiveColor[2];
materials[nummaterials-1].shininess = _material->shininess;
materials[nummaterials-1].transparency = _material->transparency;
materialsapplied = TRUE;
return (nummaterials -1); //return what index the new material got into.
}
void TriObject::addPosKey(Poskey pkey)
{
Poskey* tmp;
numposkeys ++;
if (numposkeys==1)
{
poskeys = new Poskey[numposkeys];
if (poskeys == NULL)
{
numposkeys = 0;
poskeysapplied = FALSE;
}
}
else
{
tmp = poskeys;
poskeys = new Poskey[numposkeys];
if (poskeys == NULL)
{
delete [] tmp;
numposkeys = 0;
poskeysapplied = FALSE;
}
for (i=0; i<numposkeys-1;i++)
{
poskeys[i] = tmp[i]; //Copy existing keys into the newly created array
}
}
//Insert the new key last in the array
memcpy(&poskeys[numposkeys-1], &pkey, sizeof(Poskey));
poskeysapplied = TRUE;
}
long TriObject::advanceFrame(int step, int direction, long frame)
{
if(frame == -1){
if((currentkeypostime + direction) >-1 && (currentkeypostime + direction) numposkeys+1)
{
if (poskeys[currentkeypostime+direction].time == currentframe +direction)
currentkeypostime += direction;
}
if((currentkeyrottime + direction) >-1 && (currentkeyrottime + direction) numrotkeys+1)
{
if (rotkeys[currentkeyrottime+direction].time == currentframe +direction)
currentkeyrottime += direction;
}
if((currentkeyscltime + direction) >-1 && (currentkeyscltime + direction) numsclkeys+1)
{
if (sclkeys[currentkeyscltime+direction].time == currentframe +direction)
currentkeyscltime += direction;
}
return currentframe += direction;
}
else if(frame == -2)
{
currentkeypostime = 0;
currentkeyrottime = 0;
currentkeyscltime = 0;
return currentframe = animstart;
}
else if(frame == -3)
{
currentkeypostime = numposkeys-1;
currentkeyrottime = numposkeys-1;
currentkeyscltime = numposkeys-1;
return currentframe = animend;
}
else
{
//should set frame instead of 0 ... check this sometime
currentkeypostime = 0;
currentkeyrottime = 0;
currentkeyscltime = 0;
return currentframe = frame;
}
}
void TriObject::setAnim(long start, long end)
{
animstart = start;
animend = end;
currentframe = start;
}
void TriObject::addRotKey(Rotkey rkey)
{
Rotkey* tmp;
numrotkeys ++;
if (numrotkeys==1)
{
rotkeys = new Rotkey[numrotkeys];
if (rotkeys == NULL)
{
numrotkeys = 0;
rotkeysapplied = FALSE;
}
}
else
{
tmp = rotkeys;
rotkeys = new Rotkey[numrotkeys];
if (rotkeys == NULL)
{
delete [] tmp;
numrotkeys = 0;
rotkeysapplied = FALSE;
}
for (i=0; i<numrotkeys-1;i++)
{
rotkeys[i] = tmp[i]; //Copy existing keys into the newly created array
}
}
//Insert the new key last in the array
memcpy(&rotkeys[numrotkeys-1], &rkey, sizeof(Rotkey));
rotkeysapplied = TRUE;
}
void TriObject::addSclKey(Poskey skey)
{
Poskey* tmp;
numsclkeys ++;
if (numsclkeys==1)
{
sclkeys = new Poskey[numsclkeys];
if (sclkeys == NULL)
{
numsclkeys = 0;
sclkeysapplied = FALSE;
}
}
else
{
tmp = sclkeys;
sclkeys = new Poskey[numsclkeys];
if (sclkeys == NULL)
{
delete [] tmp;
numsclkeys = 0;
sclkeysapplied = FALSE;
}
for (i=0; i<numsclkeys-1;i++)
{
sclkeys[i] = tmp[i]; //Copy existing keys into the newly created array
}
}
//Insert the new key last in the array
memcpy(&sclkeys[numsclkeys-1], &skey, sizeof(Poskey));
sclkeysapplied = TRUE;
}
void TriObject::setId(int _id)
{
id = _id;
}
int TriObject::compileDisplayList()
{
glNewList(id, GL_COMPILE);
if (normalapplied)
{
int j;
glBegin(GL_TRIANGLES);
for (i=0; i <numfaces/3; i++)
{
j = 3*i;
if(materialsapplied) glColor4f( materials[matfaces[i]].diffuseColor[0], materials[matfaces[i]].diffuseColor[1], materials[matfaces[i]].diffuseColor[2], 1/materials[matfaces[i]].transparency );
else glColor3f( 0.0f, 0.0f, 1.0f );
::glNormal3f( nx[i], ny[i], nz[i]);
::glVertex3f ( x[faces[j]] , y[faces[j]] , z[faces[j]]);
::glVertex3f( x[faces[j+1]], y[faces[j+1]], z[faces[j+1]]);
::glVertex3f( x[faces[j+2]], y[faces[j+2]], z[faces[j+2]]);
}
glEnd();
}
else
{
glBegin(GL_TRIANGLES);
for (i=0; i <numfaces; i+=3)
{
if(materialsapplied) glColor3f( materials[matfaces[i/3]].diffuseColor[0], materials[matfaces[i/3]].diffuseColor[1], materials[matfaces[i/3]].diffuseColor[2] );
else glColor3f( 0.0f, 0.0f, 1.0f );
glVertex3f( x[faces[i]] , y[faces[i]] , z[faces[i]]);
glVertex3f( x[faces[i+1]], y[faces[i+1]], z[faces[i+1]]);
glVertex3f( x[faces[i+2]], y[faces[i+2]], z[faces[i+2]]);
}
glEnd();
}
glEndList();
displistapplied = TRUE;
return id;
}
void TriObject::drawGLDispList()
{
value = currentframe *numsplrotkeys / (float)animend;
valuepos = currentframe *numsplposkeys / (float)animend;
if(poskeysapplied)
{
::glPushMatrix();
if(rotkeysapplied)
{
if(splinesapplied)
{
::glTranslatef(pivot[0] + splposmover->GetValueAtTime(0, valuepos), pivot[1] + splposmover->GetValueAtTime(1, valuepos), pivot[2] + splposmover->GetValueAtTime(2, valuepos) );
::glRotatef( splrotmover->GetValueAtTime(3, value), splrotmover->GetValueAtTime(0, value), splrotmover->GetValueAtTime(1, value), splrotmover->GetValueAtTime(2, value) );
}
else
{
::glTranslatef(pivot[0]+poskeys[currentkeypostime].pos[0], pivot[1]+poskeys[currentkeypostime].pos[1], pivot[2]+poskeys[currentkeypostime].pos[2]);
::glRotatef( rotkeys[currentkeyrottime].angle, rotkeys[currentkeyrottime].axis[0], rotkeys[currentkeyrottime].axis[1], rotkeys[currentkeyrottime].axis[2] );
}
::glTranslatef(pivot[0],pivot[1],pivot[2]);
}
}
glCallList(id);
if(poskeysapplied) ::glPopMatrix();
}
void TriObject::buildSplineAnimation()
{
//build rotation splines
//ahem. The first rotation key sets the pivotrotation
pivotrot[0] = -rotkeys[0].axis[0];
pivotrot[1] = -rotkeys[0].axis[1];
pivotrot[2] = -rotkeys[0].axis[2];
pivotrot[3] = rotkeys[0].angle * 180 / (float)M_PI;
//set null key to 0,0,0,0
splrotx.Add(0);
splroty.Add(0);
splrotz.Add(0);
splrotangle.Add(0);
splrottime.Add(0);
for(i=1; i numrotkeys; i++ )
{
if(i!=1)
{
addQuaternions(&rotkeys[i-1], &rotkeys[i]);
}
splrotx.Add(-rotkeys[i].axis[0]);
splroty.Add(-rotkeys[i].axis[1]);
splrotz.Add(-rotkeys[i].axis[2]);
splrotangle.Add(rotkeys[i].angle * 180 / (float)M_PI);
splrottime.Add(rotkeys[i].time *(numrotkeys-1)/(float)animend);
TRACE("X:%f Y:%f Z:%f ANGLE:%f TIME:%d \n",-rotkeys[i].axis[0],-rotkeys[i].axis[1],-rotkeys[i].axis[2],rotkeys[i].angle * 180 / (float)M_PI,rotkeys[i].time);
}
splrotmover = new LSmoothMover(4, &splrottime);
if (splrotmover == NULL) return;
splrotmover->SetupParamN(0,&splrotx);
splrotmover->SetupParamN(1,&splroty);
splrotmover->SetupParamN(2,&splrotz);
splrotmover->SetupParamN(3,&splrotangle);
numsplrotkeys = i-2;
//build position splines
for(i=0; i numposkeys; i++ )
{
splposx.Add(poskeys[i].pos[0]);
splposy.Add(poskeys[i].pos[1]);
splposz.Add(poskeys[i].pos[2]);
splpostime.Add(poskeys[i].time *(numposkeys)/(float)animend);
}
splposmover = new LSmoothMover(3, &splpostime);
if (splposmover == NULL) return;
splposmover->SetupParamN(0,&splposx);
splposmover->SetupParamN(1,&splposy);
splposmover->SetupParamN(2,&splposz);
splinesapplied = TRUE;
numsplposkeys = i-1;
}
void TriObject::QuatToAxisAngle(Rotkey* rkey)
{
float scale,tw;
tw = (float)acos(rkey->angle) * 2;
scale = (float)sin(tw / 2.0);
rkey->axis[0] = rkey->axis[0] / scale;
rkey->axis[1] = rkey->axis[1] / scale;
rkey->axis[2] = rkey->axis[2] / scale;
//convert the angle back to degrees
rkey->angle = (tw * (360 / 2)) / (float)M_PI;
}
void TriObject::NormalizeQuaternion(Rotkey *rkey)
{
float magnitude;
// find the magnitude
magnitude = (rkey->axis[0] * rkey->axis[0]) +
(rkey->axis[1] * rkey->axis[1]) +
(rkey->axis[2] * rkey->axis[2]) +
(rkey->angle * rkey->angle);
//catch a null quaternion
if(magnitude == 0)
{
magnitude = 1.0f;
rkey->axis[0] = 1.0f;
}
// Divide by the magnitude to normalize
rkey->axis[0] = rkey->axis[0] / magnitude;
rkey->axis[1] = rkey->axis[1] / magnitude;
rkey->axis[2] = rkey->axis[2] / magnitude;
rkey->angle = rkey->angle / magnitude;
}
void TriObject::addQuaternions(Rotkey* rkeyin, Rotkey* rkeyout)
{
float dirin = 0.0f;
float dirout = 0.0f;
dirin = rkeyin->axis[0] + rkeyin->axis[1] + rkeyin->axis[2];
dirout = rkeyout->axis[0] + rkeyout->axis[1] + rkeyout->axis[2];
if( dirout 0)
{
rkeyout->angle = rkeyin->angle - rkeyout->angle;
if (rkeyout->angle 0)
rkeyout->angle = M_2PI - (-rkeyout->angle);
}
if( dirout >= 0)
{
rkeyout->angle = rkeyin->angle + rkeyout->angle;
if (rkeyout->angle > M_2PI)
rkeyout->angle = rkeyout->angle - M_2PI;
}
}
//
// APPLYOFFSET
// This function will center the object around 0,0,0
// It is needed for correct rotation animation
// It must be called AFTER applybox()
//
void TriObject::applyOffset()
{
//return, no offset value is set
if(!bboxapplied) return;
//transform object
for(i=0; i<numvertices; i++)
{
x[i] -= offset[0];
y[i] -= offset[1];
z[i] -= offset[2];
}
//transform bounding box
for(i=0; i<8; i++)
{
bbox[i][0] -= offset[0];
bbox[i][1] -= offset[1];
bbox[i][2] -= offset[2];
}
}