📄 ast3dfract.cpp
字号:
// Ast3DFract.cpp: implementation of the CAst3DFract class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyGame.h"
#include "Ast3DFract.h"
#include "Exp.h"
#include "Fragment.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#ifdef _WIN32
#define drand48() (((float) rand())/((float) RAND_MAX))
#define srand48(x) (srand((x)))
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CAst3DFract::~CAst3DFract()
{
}
GLuint CAst3DFract::SharedTexture=0;
CAst3DFract::CAst3DFract(char *filename,float _size, int recur,int seed)
{
CMesh mm;
mm.Open(filename);
CAst3DFract(mm,_size, recur,seed);
}
CAst3DFract::CAst3DFract(CMesh &mm,float _size, int recur,int seed)
{
M=mm;
M.Normalize();
if(recur<=1)
{
recur=1;
if(_size>SmallSize) recur++;
if(_size>MediumSize) recur++;
}
if(seed==-1) seed = rand()+glutGet(GLUT_ELAPSED_TIME);
for(int i=0;i<recur;i++)
Split(seed+i,.75);
M.Smooth();
M.Normalize();
size=_size;
B.r=size/2;
M.SetTexture(SharedTexture);
M.SetMapMode(CMesh::CYLINDRICAL);
}
int CAst3DFract::Draw()
{
glPushMatrix();
glTranslate(p);
glRotatef(angle,axis.x(),axis.y(),axis.z());
glScalef(size,size,size);
glColor3f(1,1,1);
int nt=M.DrawDL();
glPopMatrix();
return nt;
}
void CAst3DFract::Split(int seed,float strenght)
{
Point3f BC(0,0,0); // The BaryCenter of the Asteroid
vector<CTriangle>::iterator i;
for(i=M.T.begin();i!=M.T.end();i++)
{
BC+=(*i).v[0].v;
BC+=(*i).v[1].v;
BC+=(*i).v[2].v;
}
BC/=(M.T.size()*3);
CMesh M2;
Point3f mp01,mp02,mp12;
for(i=M.T.begin();i!=M.T.end();i++)
{
mp01=MidPoint((*i).v[0].v,(*i).v[1].v,BC,seed,strenght);
mp02=MidPoint((*i).v[0].v,(*i).v[2].v,BC,seed,strenght);
mp12=MidPoint((*i).v[1].v,(*i).v[2].v,BC,seed,strenght);
M2.T.push_back(CTriangle((*i).v[0].v,mp01,mp02));
M2.T.push_back(CTriangle((*i).v[1].v,mp12,mp01));
M2.T.push_back(CTriangle((*i).v[2].v,mp02,mp12));
M2.T.push_back(CTriangle(mp12,mp02,mp01));
}
M=M2;
}
Point3f CAst3DFract::MidPoint(Point3f &p0, Point3f &p1, Point3f const &BC,int seed,float strenght)
{
bool swapped=false;
if(p0<p1)
{
swap(p0,p1);
swapped=true;
}
Point3f mp=(p0+p1)/2.0;
float r=(Distance(p0,BC)+Distance(p1,BC))/2.0; // Radius
float l=Distance(p0,p1); // Edge Lenght
l=l*strenght;
srand48(seed + p0.Hash() + p1.Hash());
float d=drand48()-0.5f; // Displacement depends only on the two vertexes p0,p1
mp=BC+Normalize(mp-BC)*(r+d*l/2.0);
//mp=BC+Normalize(mp-BC)*r;
if(swapped) swap(p0,p1);
return mp;
}
void CAst3DFract::Explode(list<CAst *> &AL, list<CGameObj *> &OL)
{
const int FragNum=5;
active=false;
CExp *e =new CExp();
e->p=p;
e->LightOn();
OL.push_back(e);
if(size>=CAst::MediumSize)
{
assert(Sub[0]!=0 && Sub[1]!=0);
CAst *a=Sub[0];
Point3f nv;
nv.x()=drand48()*40 - 20;
nv.y()=drand48()*40 - 20;
nv.z()=0;
a->av=20+drand48()*70;
a->axis=Normalize(Point3f(drand48(),drand48(),drand48()));
a->p=p;
a->v=v+nv;
AL.push_front(a);
a=Sub[1];
a->av=20+drand48()*70;
a->axis=Normalize(Point3f(drand48(),drand48(),drand48()));
a->p=p;
a->v=v-nv;
AL.push_front(a);
CFragment *f;
for(int i=0; i<FragNum;i++)
{
f=new CFragment();
f->p=p;
f->v=Point3f(drand48()-.5f,drand48()-.5f,0)*30;
f->axis=Normalize(Point3f(drand48(),drand48(),drand48()));
f->av=40+drand48()*100;
OL.push_front(f);
}
}
}
void CAst3DFract::GenerateSub(CMesh &AstM)
{
if(size<=SmallSize) return;
Sub.resize(2);
if(size>=LargeSize)
{
Sub[0]= new CAst3DFract(AstM,CAst::MediumSize);
Sub[1]= new CAst3DFract(AstM,CAst::MediumSize);
Sub[0]->GenerateSub(AstM);
Sub[1]->GenerateSub(AstM);
}
else
{
Sub[0]= new CAst3DFract(AstM,CAst::SmallSize);
Sub[1]= new CAst3DFract(AstM,CAst::SmallSize);
}
}
void CAst3DFract::SetSharedTexture(char *filename)
{
pngInfo info;
if(!SharedTexture) glGenTextures(1, &SharedTexture);
glBindTexture(GL_TEXTURE_2D, SharedTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
if (!pngLoad(filename, PNG_NOMIPMAP, PNG_SOLID, &info))
{
puts("Can't load file");
exit(1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -