smoketrailprojectile.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 194 行
CPP
194 行
// SmokeTrailProjectile.cpp: implementation of the CSmokeTrailProjectile class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "Game/Camera.h"
#include "Map/Ground.h"
#include "myMath.h"
#include "Rendering/GL/myGL.h"
#include "Rendering/GL/VertexArray.h"
#include "Sim/Misc/Wind.h"
#include "Sim/Projectiles/ProjectileHandler.h"
#include "SmokeTrailProjectile.h"
#include "mmgr.h"
CR_BIND_DERIVED(CSmokeTrailProjectile, CProjectile, (float3(0,0,0),float3(0,0,0),float3(0,0,0),float3(0,0,0),NULL,0,0,0,0,0,0,NULL,NULL));
CR_REG_METADATA(CSmokeTrailProjectile,(
CR_MEMBER(pos1),
CR_MEMBER(pos2),
CR_MEMBER(orgSize),
CR_MEMBER(creationTime),
CR_MEMBER(lifeTime),
CR_MEMBER(color),
CR_MEMBER(dir1),
CR_MEMBER(dir2),
CR_MEMBER(drawTrail),
CR_MEMBER(dirpos1),
CR_MEMBER(dirpos2),
CR_MEMBER(midpos),
CR_MEMBER(middir),
CR_MEMBER(drawSegmented),
CR_MEMBER(firstSegment),
CR_MEMBER(lastSegment),
CR_MEMBER(drawCallbacker),
CR_MEMBER(texture),
CR_RESERVED(4)
));
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSmokeTrailProjectile::CSmokeTrailProjectile(const float3& pos1,const float3& pos2,const float3& dir1,const float3& dir2, CUnit* owner,bool firstSegment,bool lastSegment,float size,float time,float color,bool drawTrail,CProjectile* drawCallback,AtlasedTexture* texture)
: CProjectile((pos1+pos2)*0.5f,ZeroVector,owner, false),
pos1(pos1),
pos2(pos2),
creationTime(gs->frameNum),
lifeTime((int)time),
orgSize(size),
color(color),
dir1(dir1),
dir2(dir2),
drawTrail(drawTrail),
drawSegmented(false),
drawCallbacker(drawCallback),
firstSegment(firstSegment),
lastSegment(lastSegment),
texture(texture)
{
checkCol=false;
castShadow=true;
//if no custom texture is defined, use the default texture
//Note that this will crash anyway (no idea why) so never have a null texture!
if (texture==0) {
texture = &ph->smoketrailtex;
}
if(!drawTrail){
float dist=pos1.distance(pos2);
dirpos1=pos1-dir1*dist*0.33f;
dirpos2=pos2+dir2*dist*0.33f;
} else if(dir1.dot(dir2)<0.98f){
float dist=pos1.distance(pos2);
dirpos1=pos1-dir1*dist*0.33f;
dirpos2=pos2+dir2*dist*0.33f;
float3 mp=(pos1+pos2)/2;
midpos=CalcBeizer(0.5f,pos1,dirpos1,dirpos2,pos2);
middir=(dir1+dir2).Normalize();
drawSegmented=true;
}
SetRadius(pos1.distance(pos2));
if(pos.y-ground->GetApproximateHeight(pos.x,pos.z)>10)
useAirLos=true;
}
CSmokeTrailProjectile::~CSmokeTrailProjectile()
{
}
void CSmokeTrailProjectile::Draw()
{
inArray=true;
float age=gs->frameNum+gu->timeOffset-creationTime;
if(drawTrail){
float3 dif(pos1-camera->pos2);
dif.Normalize();
float3 odir1(dif.cross(dir1));
odir1.Normalize();
float3 dif2(pos2-camera->pos2);
dif2.Normalize();
float3 odir2(dif2.cross(dir2));
odir2.Normalize();
unsigned char col[4];
float a1=(1-float(age)/(lifeTime))*255;
if(lastSegment)
a1=0;
a1*=0.7f+fabs(dif.dot(dir1));
float alpha=min(255.f,max(0.f,a1));
col[0]=(unsigned char) (color*alpha);
col[1]=(unsigned char) (color*alpha);
col[2]=(unsigned char) (color*alpha);
col[3]=(unsigned char)alpha;
unsigned char col2[4];
float a2=(1-float(age+8)/(lifeTime))*255;
if(firstSegment)
a2=0;
a2*=0.7f+fabs(dif2.dot(dir2));
alpha=min(255.f,max(0.f,a2));
col2[0]=(unsigned char) (color*alpha);
col2[1]=(unsigned char) (color*alpha);
col2[2]=(unsigned char) (color*alpha);
col2[3]=(unsigned char)alpha;
float size=1+(age*(1.0f/lifeTime))*orgSize;
float size2=1+((age+8)*(1.0f/lifeTime))*orgSize;
if(drawSegmented){
float3 dif3(midpos-camera->pos2);
dif3.Normalize();
float3 odir3(dif3.cross(middir));
odir3.Normalize();
float size3=0.2f+((age+4)*(1.0f/lifeTime))*orgSize;
unsigned char col3[4];
float a2=(1-float(age+4)/(lifeTime))*255;
a2*=0.7f+fabs(dif3.dot(middir));
alpha=min(255.f,max(0.f,a2));
col3[0]=(unsigned char) (color*alpha);
col3[1]=(unsigned char) (color*alpha);
col3[2]=(unsigned char) (color*alpha);
col3[3]=(unsigned char)alpha;
float midtexx = texture->xstart + (texture->xend - texture->xstart)*0.5f;
va->AddVertexTC(pos1-odir1*size,texture->xstart,texture->ystart,col);
va->AddVertexTC(pos1+odir1*size,texture->xstart,texture->yend,col);
va->AddVertexTC(midpos+odir3*size3,midtexx,texture->yend,col3);
va->AddVertexTC(midpos-odir3*size3,midtexx,texture->ystart,col3);
va->AddVertexTC(midpos-odir3*size3,midtexx,texture->ystart,col3);
va->AddVertexTC(midpos+odir3*size3,midtexx,texture->yend,col3);
va->AddVertexTC(pos2+odir2*size2,texture->xend,texture->yend,col2);
va->AddVertexTC(pos2-odir2*size2,texture->xend,texture->ystart,col2);
} else {
va->AddVertexTC(pos1-odir1*size,texture->xstart,texture->ystart,col);
va->AddVertexTC(pos1+odir1*size,texture->xstart,texture->yend,col);
va->AddVertexTC(pos2+odir2*size2,texture->xend,texture->yend,col2);
va->AddVertexTC(pos2-odir2*size2,texture->xend,texture->ystart,col2);
}
} else { //draw as particles
unsigned char col[4];
for(int a=0;a<8;++a){
float a1=1-float(age+a)/lifeTime;
float alpha=min(255.f,max(0.f,a1*255));
col[0]=(unsigned char) (color*alpha);
col[1]=(unsigned char) (color*alpha);
col[2]=(unsigned char) (color*alpha);
col[3]=(unsigned char)alpha;
float size=((0.2f+(age+a)*(1.0f/lifeTime))*orgSize)*1.2f;
float3 pos=CalcBeizer(a/8.0f,pos1,dirpos1,dirpos2,pos2);
va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
}
}
if(drawCallbacker)
drawCallbacker->DrawCallback();
}
void CSmokeTrailProjectile::Update()
{
if(gs->frameNum>=creationTime+lifeTime)
deleteMe=true;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?