📄 featurehandler.cpp
字号:
}
delete[] mfi;
}
}
int CFeatureHandler::AddFeature(CFeature* feature)
{
ASSERT_SYNCED_MODE;
if (freeIDs.empty()) {
feature->id = nextFreeID++;
} else {
feature->id = freeIDs.front();
freeIDs.pop_front();
}
activeFeatures.insert(feature);
SetFeatureUpdateable(feature);
if(feature->def->drawType==DRAWTYPE_3DO){
int quad = int(feature->pos.z / DRAW_QUAD_SIZE / SQUARE_SIZE) * drawQuadsX +
int(feature->pos.x / DRAW_QUAD_SIZE / SQUARE_SIZE);
DrawQuad* dq=&drawQuads[quad];
dq->features.insert(feature);
feature->drawQuad=quad;
}
luaCallIns.FeatureCreated(feature);
return feature->id ;
}
void CFeatureHandler::DeleteFeature(CFeature* feature)
{
ASSERT_SYNCED_MODE;
toBeRemoved.push_back(feature->id);
luaCallIns.FeatureDestroyed(feature);
}
CFeature* CFeatureHandler::CreateWreckage(const float3& pos, const std::string& name,
float rot, int facing, int iter, int team,
int allyteam, bool emitSmoke,std::string fromUnit)
{
ASSERT_SYNCED_MODE;
if (name.empty()) {
return NULL;
}
const FeatureDef* fd = GetFeatureDef(name);
if (!fd) {
return NULL;
}
if (iter > 1) {
return CreateWreckage(pos, fd->deathFeature, rot, facing, iter - 1, team, allyteam, emitSmoke, "");
}
else {
if (luaRules && !luaRules->AllowFeatureCreation(fd, team, pos)) {
return NULL;
}
if(!fd->modelname.empty()){
CFeature* f=SAFE_NEW CFeature;
f->Initialize (pos, fd, (short int)rot, facing, team, fromUnit);
// allow area-reclaiming wrecks of all units, including your own (they set allyteam = -1)
f->allyteam = allyteam;
if(emitSmoke && f->blocking)
f->emitSmokeTime=300;
return f;
}
}
return NULL;
}
void CFeatureHandler::Update()
{
ASSERT_SYNCED_MODE;
SCOPED_TIMER("Feature::Update");
if ((gs->frameNum & 31) == 0) // let all areareclaimers choose a target with a different id
freeIDs.splice(freeIDs.end(), toBeFreedIDs, toBeFreedIDs.begin(), toBeFreedIDs.end());
while (!toBeRemoved.empty()) {
CFeatureSet::iterator it = activeFeatures.find(toBeRemoved.back());
toBeRemoved.pop_back();
if (it != activeFeatures.end()) {
CFeature* feature = *it;
toBeFreedIDs.push_back(feature->id);
activeFeatures.erase(feature);
if (feature->drawQuad >= 0) {
DrawQuad* dq = &drawQuads[feature->drawQuad];
dq->features.erase(feature);
}
if (feature->inUpdateQue) {
updateFeatures.erase(feature);
}
delete feature;
}
}
CFeatureSet::iterator fi=updateFeatures.begin();
while (fi != updateFeatures.end()) {
CFeature* feature = *fi;
++fi;
if (!feature->Update()) {
// remove it
feature->inUpdateQue = false;
updateFeatures.erase(feature);
}
}
}
void CFeatureHandler::UpdateDrawQuad(CFeature* feature, const float3& newPos)
{
const int oldDrawQuad = feature->drawQuad;
if (oldDrawQuad >= 0) {
const int newDrawQuad =
int(newPos.z / DRAW_QUAD_SIZE / SQUARE_SIZE) * drawQuadsX +
int(newPos.x / DRAW_QUAD_SIZE / SQUARE_SIZE);
if (oldDrawQuad != newDrawQuad) {
DrawQuad* oldDQ = &drawQuads[oldDrawQuad];
oldDQ->features.erase(feature);
DrawQuad* newDQ = &drawQuads[newDrawQuad];
newDQ->features.insert(feature);
feature->drawQuad = newDrawQuad;
}
}
}
void CFeatureHandler::SetFeatureUpdateable(CFeature* feature)
{
if (feature->inUpdateQue) {
return;
}
updateFeatures.insert(feature);
feature->inUpdateQue = true;
}
void CFeatureHandler::TerrainChanged(int x1, int y1, int x2, int y2)
{
ASSERT_SYNCED_MODE;
vector<int> quads=qf->GetQuadsRectangle(float3(x1*SQUARE_SIZE,0,y1*SQUARE_SIZE),
float3(x2*SQUARE_SIZE,0,y2*SQUARE_SIZE));
// logOutput.Print("Checking feature pos %i",quads.size());
for(vector<int>::iterator qi=quads.begin();qi!=quads.end();++qi){
list<CFeature*>::iterator fi;
list<CFeature*>& features = qf->baseQuads[*qi].features;
for(fi = features.begin(); fi != features.end(); ++fi) {
CFeature* feature = *fi;
float3& fpos = feature->pos;
if (fpos.y > ground->GetHeight(fpos.x, fpos.z)) {
SetFeatureUpdateable(feature);
if (feature->def->floating){
feature->finalHeight = ground->GetHeight(fpos.x, fpos.z);
} else {
feature->finalHeight = ground->GetHeight2(fpos.x, fpos.z);
}
feature->CalculateTransform ();
}
}
}
}
void CFeatureHandler::Draw()
{
ASSERT_UNSYNCED_MODE;
vector<CFeature*> drawFar;
unitDrawer->SetupForUnitDrawing();
DrawRaw(0, &drawFar);
unitDrawer->CleanUpUnitDrawing();
unitDrawer->DrawQuedS3O();
CVertexArray* va=GetVertexArray();
va->Initialize();
glAlphaFunc(GL_GREATER,0.8f);
glEnable(GL_ALPHA_TEST);
glBindTexture(GL_TEXTURE_2D,fartextureHandler->farTexture);
glColor3f(1,1,1);
glEnable(GL_FOG);
for(vector<CFeature*>::iterator usi=drawFar.begin();usi!=drawFar.end();usi++){
DrawFar(*usi,va);
}
va->DrawArrayTN(GL_QUADS);
}
void CFeatureHandler::DrawShadowPass()
{
ASSERT_UNSYNCED_MODE;
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, unitDrawer->unitShadowGenVP );
glEnable( GL_VERTEX_PROGRAM_ARB );
glPolygonOffset(1,1);
glEnable(GL_POLYGON_OFFSET_FILL);
unitDrawer->SetupForUnitDrawing();
DrawRaw(1, NULL);
unitDrawer->CleanUpUnitDrawing();
unitDrawer->DrawQuedS3O();
glDisable(GL_POLYGON_OFFSET_FILL);
glDisable( GL_VERTEX_PROGRAM_ARB );
}
class CFeatureDrawer : public CReadMap::IQuadDrawer
{
public:
void DrawQuad (int x,int y);
CFeatureHandler *fh;
// CFeatureHandler::DrawQuad *drawQuads;
std::vector<CFeatureHandler::DrawQuad> *drawQuads;
int drawQuadsX;
bool drawReflection, drawRefraction;
float unitDrawDist;
std::vector<CFeature*>* farFeatures;
};
void CFeatureDrawer::DrawQuad (int x,int y)
{
CFeatureHandler::DrawQuad* dq=&(*drawQuads)[y*drawQuadsX+x];
for (CFeatureSet::iterator fi = dq->features.begin(); fi != dq->features.end(); ++fi) {
CFeature* f = (*fi);
const FeatureDef* def = f->def;
if((f->allyteam==-1 || f->allyteam==gu->myAllyTeam ||
loshandler->InLos(f->pos,gu->myAllyTeam) || gu->spectatingFullView)
&& def->drawType==DRAWTYPE_3DO){
if(drawReflection){
float3 zeroPos;
if(f->midPos.y<0){
zeroPos=f->midPos;
}else{
float dif=f->midPos.y-camera->pos.y;
zeroPos=camera->pos*(f->midPos.y/dif) + f->midPos*(-camera->pos.y/dif);
}
if(ground->GetApproximateHeight(zeroPos.x,zeroPos.z)>f->radius){
continue;
}
}
if(drawRefraction){
if(f->pos.y>0)
continue;
}
float sqDist=(f->pos-camera->pos).SqLength2D();
float farLength=f->sqRadius*unitDrawDist*unitDrawDist;
if(sqDist<farLength){
if(!f->model->textureType) {
f->DrawS3O ();
} else {
unitDrawer->QueS3ODraw(f,f->model->textureType);
}
} else {
if(farFeatures)
farFeatures->push_back(f);
}
}
}
}
void CFeatureHandler::DrawRaw(int extraSize, std::vector<CFeature*>* farFeatures)
{
float featureDist=3000;
if(!extraSize)
featureDist=6000; //farfeatures wont be drawn for shadowpass anyway
CFeatureDrawer drawer;
drawer.drawQuads = &drawQuads;
drawer.fh = this;
drawer.drawQuadsX = drawQuadsX;
drawer.drawReflection=water->drawReflection;
drawer.drawRefraction=water->drawRefraction;
drawer.unitDrawDist=unitDrawer->unitDrawDist;
drawer.farFeatures = farFeatures;
readmap->GridVisibility (camera, DRAW_QUAD_SIZE, featureDist, &drawer, extraSize);
}
void CFeatureHandler::DrawFar(CFeature* feature, CVertexArray* va)
{
float3 interPos=feature->pos+UpVector*feature->model->height*0.5f;
int snurr=-feature->heading+GetHeadingFromVector(camera->pos.x-feature->pos.x,camera->pos.z-feature->pos.z)+(0xffff>>4);
if(snurr<0)
snurr+=0xffff;
if(snurr>0xffff)
snurr-=0xffff;
snurr=snurr>>13;
float tx=(feature->model->farTextureNum%8)*(1.0f/8.0f)+snurr*(1.0f/64);
float ty=(feature->model->farTextureNum/8)*(1.0f/64.0f);
float offset=0;
va->AddVertexTN(interPos-(camera->up*feature->radius*1.4f-offset)+camera->right*feature->radius,tx,ty,unitDrawer->camNorm);
va->AddVertexTN(interPos+(camera->up*feature->radius*1.4f+offset)+camera->right*feature->radius,tx,ty+(1.0f/64.0f),unitDrawer->camNorm);
va->AddVertexTN(interPos+(camera->up*feature->radius*1.4f+offset)-camera->right*feature->radius,tx+(1.0f/64.0f),ty+(1.0f/64.0f),unitDrawer->camNorm);
va->AddVertexTN(interPos-(camera->up*feature->radius*1.4f-offset)-camera->right*feature->radius,tx+(1.0f/64.0f),ty,unitDrawer->camNorm);
}
S3DOModel* FeatureDef::LoadModel(int team) const
{
if (!useCSOffset) {
return modelParser->Load3DO(modelname.c_str(),
collisionSphereScale, team);
} else {
return modelParser->Load3DO(modelname.c_str(),
collisionSphereScale, team,
collisionSphereOffset);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -