📄 lesson30.cpp
字号:
{
normal=norm;
point=Nc;
lamda=rt4;
BallNr=i;
}
}
}
if (TestIntersionCylinder(cyl2,OldPos[i],uveloc,rt,norm,Nc))
{
rt4=rt*RestTime/rt2;
if (rt4<=lamda)
{
if (rt4<=RestTime+ZERO)
if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )
{
normal=norm;
point=Nc;
lamda=rt4;
BallNr=i;
}
}
}
if (TestIntersionCylinder(cyl3,OldPos[i],uveloc,rt,norm,Nc))
{
rt4=rt*RestTime/rt2;
if (rt4<=lamda)
{
if (rt4<=RestTime+ZERO)
if (! ((rt<=ZERO)&&(uveloc.dot(norm)>ZERO)) )
{
normal=norm;
point=Nc;
lamda=rt4;
BallNr=i;
}
}
}
}
//After all balls were teste with planes/cylinders test for collision
//between them and replace if collision time smaller
if (FindBallCol(Pos2,BallTime,RestTime,BallColNr1,BallColNr2))
{
if (sounds)
PlaySound("Data/Explode.wav",NULL,SND_FILENAME|SND_ASYNC);
if ( (lamda==10000) || (lamda>BallTime) )
{
RestTime=RestTime-BallTime;
TVector pb1,pb2,xaxis,U1x,U1y,U2x,U2y,V1x,V1y,V2x,V2y;
double a,b;
pb1=OldPos[BallColNr1]+ArrayVel[BallColNr1]*BallTime;
pb2=OldPos[BallColNr2]+ArrayVel[BallColNr2]*BallTime;
xaxis=(pb2-pb1).unit();
a=xaxis.dot(ArrayVel[BallColNr1]);
U1x=xaxis*a;
U1y=ArrayVel[BallColNr1]-U1x;
xaxis=(pb1-pb2).unit();
b=xaxis.dot(ArrayVel[BallColNr2]);
U2x=xaxis*b;
U2y=ArrayVel[BallColNr2]-U2x;
V1x=(U1x+U2x-(U1x-U2x))*0.5;
V2x=(U1x+U2x-(U2x-U1x))*0.5;
V1y=U1y;
V2y=U2y;
for (j=0;j<NrOfBalls;j++)
ArrayPos[j]=OldPos[j]+ArrayVel[j]*BallTime;
ArrayVel[BallColNr1]=V1x+V1y;
ArrayVel[BallColNr2]=V2x+V2y;
//Update explosion array
for(j=0;j<20;j++)
{
if (ExplosionArray[j]._Alpha<=0)
{
ExplosionArray[j]._Alpha=1;
ExplosionArray[j]._Position=ArrayPos[BallColNr1];
ExplosionArray[j]._Scale=1;
break;
}
}
continue;
}
}
//End of tests
//If test occured move simulation for the correct timestep
//and compute response for the colliding ball
if (lamda!=10000)
{
RestTime-=lamda;
for (j=0;j<NrOfBalls;j++)
ArrayPos[j]=OldPos[j]+ArrayVel[j]*lamda;
rt2=ArrayVel[BallNr].mag();
ArrayVel[BallNr].unit();
ArrayVel[BallNr]=TVector::unit( (normal*(2*normal.dot(-ArrayVel[BallNr]))) + ArrayVel[BallNr] );
ArrayVel[BallNr]=ArrayVel[BallNr]*rt2;
//Update explosion array
for(j=0;j<20;j++)
{
if (ExplosionArray[j]._Alpha<=0)
{
ExplosionArray[j]._Alpha=1;
ExplosionArray[j]._Position=point;
ExplosionArray[j]._Scale=1;
break;
}
}
}
else RestTime=0;
}
}
/*************************************************************************************/
/*************************************************************************************/
/*** Init Variables ****/
/*************************************************************************************/
/*************************************************************************************/
void InitVars()
{
//create palnes
pl1._Position=TVector(0,-300,0);
pl1._Normal=TVector(0,1,0);
pl2._Position=TVector(300,0,0);
pl2._Normal=TVector(-1,0,0);
pl3._Position=TVector(-300,0,0);
pl3._Normal=TVector(1,0,0);
pl4._Position=TVector(0,0,300);
pl4._Normal=TVector(0,0,-1);
pl5._Position=TVector(0,0,-300);
pl5._Normal=TVector(0,0,1);
//create cylinders
cyl1._Position=TVector(0,0,0);
cyl1._Axis=TVector(0,1,0);
cyl1._Radius=60+20;
cyl2._Position=TVector(200,-300,0);
cyl2._Axis=TVector(0,0,1);
cyl2._Radius=60+20;
cyl3._Position=TVector(-200,0,0);
cyl3._Axis=TVector(0,1,1);
cyl3._Axis.unit();
cyl3._Radius=30+20;
//create quadratic object to render cylinders
cylinder_obj= gluNewQuadric();
gluQuadricTexture(cylinder_obj, GL_TRUE);
//Set initial positions and velocities of balls
//also initialize array which holds explosions
NrOfBalls=10;
ArrayVel[0]=veloc;
ArrayPos[0]=TVector(199,180,10);
ExplosionArray[0]._Alpha=0;
ExplosionArray[0]._Scale=1;
ArrayVel[1]=veloc;
ArrayPos[1]=TVector(0,150,100);
ExplosionArray[1]._Alpha=0;
ExplosionArray[1]._Scale=1;
ArrayVel[2]=veloc;
ArrayPos[2]=TVector(-100,180,-100);
ExplosionArray[2]._Alpha=0;
ExplosionArray[2]._Scale=1;
for (int i=3; i<10; i++)
{
ArrayVel[i]=veloc;
ArrayPos[i]=TVector(-500+i*75, 300, -500+i*50);
ExplosionArray[i]._Alpha=0;
ExplosionArray[i]._Scale=1;
}
for (i=10; i<20; i++)
{
ExplosionArray[i]._Alpha=0;
ExplosionArray[i]._Scale=1;
}
}
/*************************************************************************************/
/*************************************************************************************/
/*** Fast Intersection Function between ray/plane ****/
/*************************************************************************************/
/*************************************************************************************/
int TestIntersionPlane(const Plane& plane,const TVector& position,const TVector& direction, double& lamda, TVector& pNormal)
{
double DotProduct=direction.dot(plane._Normal);
double l2;
//determine if ray paralle to plane
if ((DotProduct<ZERO)&&(DotProduct>-ZERO))
return 0;
l2=(plane._Normal.dot(plane._Position-position))/DotProduct;
if (l2<-ZERO)
return 0;
pNormal=plane._Normal;
lamda=l2;
return 1;
}
/*************************************************************************************/
/*************************************************************************************/
/*** Fast Intersection Function between ray/cylinder ****/
/*************************************************************************************/
int TestIntersionCylinder(const Cylinder& cylinder,const TVector& position,const TVector& direction, double& lamda, TVector& pNormal,TVector& newposition)
{
TVector RC;
double d;
double t,s;
TVector n,D,O;
double ln;
double in,out;
TVector::subtract(position,cylinder._Position,RC);
TVector::cross(direction,cylinder._Axis,n);
ln=n.mag();
if ( (ln<ZERO)&&(ln>-ZERO) ) return 0;
n.unit();
d= fabs( RC.dot(n) );
if (d<=cylinder._Radius)
{
TVector::cross(RC,cylinder._Axis,O);
t= - O.dot(n)/ln;
TVector::cross(n,cylinder._Axis,O);
O.unit();
s= fabs( sqrt(cylinder._Radius*cylinder._Radius - d*d) / direction.dot(O) );
in=t-s;
out=t+s;
if (in<-ZERO){
if (out<-ZERO) return 0;
else lamda=out;
}
else
if (out<-ZERO) {
lamda=in;
}
else
if (in<out) lamda=in;
else lamda=out;
newposition=position+direction*lamda;
TVector HB=newposition-cylinder._Position;
pNormal=HB - cylinder._Axis*(HB.dot(cylinder._Axis));
pNormal.unit();
return 1;
}
return 0;
}
/*************************************************************************************/
/*************************************************************************************/
/*** Load Bitmaps And Convert To Textures ****/
/*************************************************************************************/
void LoadGLTextures() {
/* Load Texture*/
Image *image1, *image2, *image3, *image4;
/* allocate space for texture*/
image1 = (Image *) malloc(sizeof(Image));
if (image1 == NULL) {
printf("Error allocating space for image");
exit(0);
}
image2 = (Image *) malloc(sizeof(Image));
if (image2 == NULL) {
printf("Error allocating space for image");
exit(0);
}
image3 = (Image *) malloc(sizeof(Image));
if (image3 == NULL) {
printf("Error allocating space for image");
exit(0);
}
image4 = (Image *) malloc(sizeof(Image));
if (image4 == NULL) {
printf("Error allocating space for image");
exit(0);
}
if (!ImageLoad("data/marble.bmp", image1)) {
exit(1);
}
if (!ImageLoad("data/spark.bmp", image2)) {
exit(1);
}
if (!ImageLoad("data/boden.bmp", image3)) {
exit(1);
}
if (!ImageLoad("data/wand.bmp", image4)) {
exit(1);
}
/* Create Texture *****************************************/
glGenTextures(2, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]); /* 2d texture (x and y size)*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); /* scale linearly when image bigger than texture*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); /* scale linearly when image smalled than texture*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
/* 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, */
/* border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.*/
glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->data);
/* Create Texture ******************************************/
glBindTexture(GL_TEXTURE_2D, texture[1]); /* 2d texture (x and y size)*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); /* scale linearly when image bigger than texture*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); /* scale linearly when image smalled than texture*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
/* 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, */
/* border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.*/
glTexImage2D(GL_TEXTURE_2D, 0, 3, image2->sizeX, image2->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image2->data);
/* Create Texture ********************************************/
glGenTextures(2, &texture[2]);
glBindTexture(GL_TEXTURE_2D, texture[2]); /* 2d texture (x and y size)*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); /* scale linearly when image bigger than texture*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); /* scale linearly when image smalled than texture*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
/* 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, */
/* border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.*/
glTexImage2D(GL_TEXTURE_2D, 0, 3, image3->sizeX, image3->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image3->data);
/* Create Texture *********************************************/
glBindTexture(GL_TEXTURE_2D, texture[3]); /* 2d texture (x and y size)*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); /* scale linearly when image bigger than texture*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); /* scale linearly when image smalled than texture*/
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
/* 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, */
/* border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.*/
glTexImage2D(GL_TEXTURE_2D, 0, 3, image4->sizeX, image4->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image4->data);
free(image1->data);
free(image1);
free(image2->data);
free(image2);
free(image3->data);
free(image3);
free(image4->data);
free(image4);
};
int ProcessKeys()
{
if (keys[VK_UP]) pos+=TVector(0,0,-10);
if (keys[VK_UP]) pos+=TVector(0,0,10);
if (keys[VK_LEFT]) camera_rotation+=10;
if (keys[VK_RIGHT]) camera_rotation-=10;
if (keys[VK_ADD])
{
Time+=0.1;
keys[VK_ADD]=FALSE;
}
if (keys[VK_SUBTRACT])
{
Time-=0.1;
keys[VK_SUBTRACT]=FALSE;
}
if (keys[VK_F3])
{
sounds^=1;
keys[VK_F3]=FALSE;
}
if (keys[VK_F2])
{
hook_toball1^=1;
camera_rotation=0;
keys[VK_F2]=FALSE;
}
if (keys[VK_F1]) // Is F1 Being Pressed?
{
keys[VK_F1]=FALSE; // If So Make Key FALSE
KillGLWindow(); // Kill Our Current Window
fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode
// Recreate Our OpenGL Window
if (!CreateGLWindow("Magic Room",640,480,16,fullscreen))
{
return 0; // Quit If Window Was Not Created
}
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -