/* ============== SearchForEnemy This function is used to search for something for the bot to shoot at ============== */ void SearchForEnemy (client_t *client) {//for a normal game edict_t *bot = client->edict; edict_t *nmy = bot->bot.enemy; vec3_t eyes1, eyes2, test; int num; if (nmy != bot && // If he has an enemy that aint himself nmy->v.health > 0) // and has some health { VectorAdd (nmy->v.origin, nmy->v.view_ofs, eyes1); // We want the origin of the enemies eyes VectorAdd (bot->v.origin, bot->v.view_ofs, eyes2); // We want the origin of the bots eyes if (IsInView(eyes1, eyes2, bot, nmy, 120, test)) // test if its in view { VectorCopy (test, bot->v.angles); // Then turn towards the enemy AttackMoveBot (client, true, true, true, nmy); // and start running and shooting return; // We are done here now... } } // Guess we had no enemy or couldnt see him anymore bot->bot.enemy = bot; // Set enemy to the bot himself again nmy = Nextent(globot.world); // Prepare to loop through clients num = 0; //save up to 31 calculations VectorAdd (bot->v.origin, bot->v.view_ofs, eyes2); // We want the origin of the bots eyes while (num < globot.MaxClients) // Keep looping as long as there are clients { if (nmy->bot.Active && // Enemy is playing nmy != bot && // and is not the bot himself nmy->v.health > 0)// && // and is alive //nmy->v.team != bot->v.team) // and in another team { VectorAdd (nmy->v.origin, nmy->v.view_ofs, eyes1); // We want the origin of the clients eyes if (IsInView(eyes1, eyes2, bot, nmy, 120, test)) // test if its in view { bot->bot.enemy = nmy; // Then set him as the enemy VectorCopy (test, bot->v.angles); // Then turn to the enemy AttackMoveBot (client, true, true, true, nmy); // and start running, jumping and shooting return; // We are done here now... } } num++; nmy = Nextent(nmy); // If the client wasn't visible then continue the loop with the next client } // Guess we found no enemies bot->v.angles[0] = 0; bot->v.angles[2] = 0; bot->v.button0 = 0; // So why waste ammo? }
void WorldInternal::Culling(const Matrix44& cameraProjMat, bool isOpenGL) { objs.clear(); #ifdef _WIN32 if (_finite(cameraProjMat.Values[2][2]) != 0 && cameraProjMat.Values[0][0] != 0.0f && cameraProjMat.Values[1][1] != 0.0f) { #else if (isfinite(cameraProjMat.Values[2][2]) != 0 && cameraProjMat.Values[0][0] != 0.0f && cameraProjMat.Values[1][1] != 0.0f) { #endif Matrix44 cameraProjMatInv = cameraProjMat; cameraProjMatInv.SetInverted(); float maxx = 1.0f; float minx = -1.0f; float maxy = 1.0f; float miny = -1.0f; float maxz = 1.0f; float minz = 0.0f; if (isOpenGL) minz = -1.0f; Vector3DF eyebox[8]; eyebox[0 + 0] = Vector3DF(minx, miny, maxz); eyebox[1 + 0] = Vector3DF(maxx, miny, maxz); eyebox[2 + 0] = Vector3DF(minx, maxy, maxz); eyebox[3 + 0] = Vector3DF(maxx, maxy, maxz); eyebox[0 + 4] = Vector3DF(minx, miny, minz); eyebox[1 + 4] = Vector3DF(maxx, miny, minz); eyebox[2 + 4] = Vector3DF(minx, maxy, minz); eyebox[3 + 4] = Vector3DF(maxx, maxy, minz); for (int32_t i = 0; i < 8; i++) { eyebox[i] = cameraProjMatInv.Transform3D(eyebox[i]); } // 0-right 1-left 2-top 3-bottom 4-front 5-back Vector3DF facePositions[6]; facePositions[0] = eyebox[5]; facePositions[1] = eyebox[4]; facePositions[2] = eyebox[6]; facePositions[3] = eyebox[4]; facePositions[4] = eyebox[4]; facePositions[5] = eyebox[0]; Vector3DF faceDir[6]; faceDir[0] = Vector3DF::Cross(eyebox[1] - eyebox[5], eyebox[7] - eyebox[5]); faceDir[1] = Vector3DF::Cross(eyebox[6] - eyebox[4], eyebox[0] - eyebox[4]); faceDir[2] = Vector3DF::Cross(eyebox[7] - eyebox[6], eyebox[2] - eyebox[6]); faceDir[3] = Vector3DF::Cross(eyebox[0] - eyebox[4], eyebox[5] - eyebox[4]); faceDir[4] = Vector3DF::Cross(eyebox[5] - eyebox[4], eyebox[6] - eyebox[4]); faceDir[5] = Vector3DF::Cross(eyebox[2] - eyebox[0], eyebox[1] - eyebox[5]); for (int32_t i = 0; i < 6; i++) { faceDir[i].Normalize(); } for (int32_t z = 0; z < viewCullingZDiv; z++) { for (int32_t y = 0; y < viewCullingYDiv; y++) { for (int32_t x = 0; x < viewCullingXDiv; x++) { Vector3DF eyebox_[8]; float xsize = 1.0f / (float) viewCullingXDiv; float ysize = 1.0f / (float) viewCullingYDiv; float zsize = 1.0f / (float) viewCullingZDiv; for (int32_t e = 0; e < 8; e++) { float x_, y_, z_; if (e == 0){ x_ = xsize * x; y_ = ysize * y; z_ = zsize * z; } if (e == 1){ x_ = xsize * (x + 1); y_ = ysize * y; z_ = zsize * z; } if (e == 2){ x_ = xsize * x; y_ = ysize * (y + 1); z_ = zsize * z; } if (e == 3){ x_ = xsize * (x + 1); y_ = ysize * (y + 1); z_ = zsize * z; } if (e == 4){ x_ = xsize * x; y_ = ysize * y; z_ = zsize * (z + 1); } if (e == 5){ x_ = xsize * (x + 1); y_ = ysize * y; z_ = zsize * (z + 1); } if (e == 6){ x_ = xsize * x; y_ = ysize * (y + 1); z_ = zsize * (z + 1); } if (e == 7){ x_ = xsize * (x + 1); y_ = ysize * (y + 1); z_ = zsize * (z + 1); } Vector3DF yzMid[4]; yzMid[0] = eyebox[0] * x_ + eyebox[1] * (1.0f - x_); yzMid[1] = eyebox[2] * x_ + eyebox[3] * (1.0f - x_); yzMid[2] = eyebox[4] * x_ + eyebox[5] * (1.0f - x_); yzMid[3] = eyebox[6] * x_ + eyebox[7] * (1.0f - x_); Vector3DF zMid[2]; zMid[0] = yzMid[0] * y_ + yzMid[1] * (1.0f - y_); zMid[1] = yzMid[2] * y_ + yzMid[3] * (1.0f - y_); eyebox_[e] = zMid[0] * z_ + zMid[1] * (1.0f - z_); } Vector3DF max_(-FLT_MAX, -FLT_MAX, -FLT_MAX); Vector3DF min_(FLT_MAX, FLT_MAX, FLT_MAX); for (int32_t i = 0; i < 8; i++) { if (eyebox_[i].X > max_.X) max_.X = eyebox_[i].X; if (eyebox_[i].Y > max_.Y) max_.Y = eyebox_[i].Y; if (eyebox_[i].Z > max_.Z) max_.Z = eyebox_[i].Z; if (eyebox_[i].X < min_.X) min_.X = eyebox_[i].X; if (eyebox_[i].Y < min_.Y) min_.Y = eyebox_[i].Y; if (eyebox_[i].Z < min_.Z) min_.Z = eyebox_[i].Z; } /* 範囲内に含まれるグリッドを取得 */ for (size_t i = 0; i < layers.size(); i++) { layers[i]->AddGrids(max_, min_, grids); } } } } /* 外領域追加 */ grids.push_back(&outofLayers); grids.push_back(&allLayers); /* グリッドからオブジェクト取得 */ for (size_t i = 0; i < grids.size(); i++) { for (size_t j = 0; j < grids[i]->GetObjects().size(); j++) { Object* o = grids[i]->GetObjects()[j]; ObjectInternal* o_ = (ObjectInternal*) o; if ( o_->GetNextStatus().Type == OBJECT_SHAPE_TYPE_ALL || IsInView(o_->GetPosition(), o_->GetNextStatus().CalcRadius(), facePositions, faceDir)) { objs.push_back(o); } } } /* 取得したグリッドを破棄 */ for (size_t i = 0; i < grids.size(); i++) { grids[i]->IsScanned = false; } grids.clear(); } else { grids.push_back(&allLayers); /* グリッドからオブジェクト取得 */ for (size_t i = 0; i < grids.size(); i++) { for (size_t j = 0; j < grids[i]->GetObjects().size(); j++) { Object* o = grids[i]->GetObjects()[j]; ObjectInternal* o_ = (ObjectInternal*) o; if (o_->GetNextStatus().Type == OBJECT_SHAPE_TYPE_ALL) { objs.push_back(o); } } } /* 取得したグリッドを破棄 */ for (size_t i = 0; i < grids.size(); i++) { grids[i]->IsScanned = false; } grids.clear(); } } bool WorldInternal::Reassign() { /* 数が少ない */ if (outofLayers.GetObjects().size() < 10) return false; objs.clear(); for (size_t i = 0; i < layers.size(); i++) { delete layers[i]; } layers.clear(); outofLayers.GetObjects().clear(); allLayers.GetObjects().clear(); outofLayers.IsScanned = false; allLayers.IsScanned = false; for (auto& it : containedObjects) { auto o = (ObjectInternal*) (it); o->ObjectIndex = -1; } float xmin = FLT_MAX; float xmax = -FLT_MAX; float ymin = FLT_MAX; float ymax = -FLT_MAX; float zmin = FLT_MAX; float zmax = -FLT_MAX; for (auto& it : containedObjects) { ObjectInternal* o_ = (ObjectInternal*) it; if (o_->GetNextStatus().Type == OBJECT_SHAPE_TYPE_ALL) continue; if (xmin > o_->GetNextStatus().Position.X) xmin = o_->GetNextStatus().Position.X; if (xmax < o_->GetNextStatus().Position.X) xmax = o_->GetNextStatus().Position.X; if (ymin > o_->GetNextStatus().Position.Y) ymin = o_->GetNextStatus().Position.Y; if (ymax < o_->GetNextStatus().Position.Y) ymax = o_->GetNextStatus().Position.Y; if (zmin > o_->GetNextStatus().Position.Z) zmin = o_->GetNextStatus().Position.Z; if (zmax < o_->GetNextStatus().Position.Z) zmax = o_->GetNextStatus().Position.Z; } auto xlen = Max(abs(xmax), abs(xmin)) * 2.0f; auto ylen = Max(abs(ymax), abs(ymin)) * 2.0f; auto zlen = Max(abs(zmax), abs(zmin)) * 2.0f; WorldInternal(xlen, ylen, zlen, this->layerCount); for (auto& it: containedObjects) { ObjectInternal* o_ = (ObjectInternal*) (it); AddObjectInternal(o_); } return true; } void WorldInternal::Dump(const char* path, const Matrix44& cameraProjMat, bool isOpenGL) { std::ofstream ofs(path); /* カメラ情報出力 */ Matrix44 cameraProjMatInv = cameraProjMat; cameraProjMatInv.SetInverted(); float maxx = 1.0f; float minx = -1.0f; float maxy = 1.0f; float miny = -1.0f; float maxz = 1.0f; float minz = 0.0f; if (isOpenGL) minz = -1.0f; Vector3DF eyebox[8]; eyebox[0 + 0] = Vector3DF(minx, miny, maxz); eyebox[1 + 0] = Vector3DF(maxx, miny, maxz); eyebox[2 + 0] = Vector3DF(minx, maxy, maxz); eyebox[3 + 0] = Vector3DF(maxx, maxy, maxz); eyebox[0 + 4] = Vector3DF(minx, miny, minz); eyebox[1 + 4] = Vector3DF(maxx, miny, minz); eyebox[2 + 4] = Vector3DF(minx, maxy, minz); eyebox[3 + 4] = Vector3DF(maxx, maxy, minz); for (int32_t i = 0; i < 8; i++) { eyebox[i] = cameraProjMatInv.Transform3D(eyebox[i]); } ofs << viewCullingXDiv << "," << viewCullingYDiv << "," << viewCullingZDiv << std::endl; for (int32_t i = 0; i < 8; i++) { ofs << eyebox[i].X << "," << eyebox[i].Y << "," << eyebox[i].Z << std::endl; } ofs << std::endl; for (int32_t z = 0; z < viewCullingZDiv; z++) { for (int32_t y = 0; y < viewCullingYDiv; y++) { for (int32_t x = 0; x < viewCullingXDiv; x++) { Vector3DF eyebox_[8]; float xsize = 1.0f / (float) viewCullingXDiv; float ysize = 1.0f / (float) viewCullingYDiv; float zsize = 1.0f / (float) viewCullingZDiv; for (int32_t e = 0; e < 8; e++) { float x_, y_, z_; if (e == 0){ x_ = xsize * x; y_ = ysize * y; z_ = zsize * z; } if (e == 1){ x_ = xsize * (x + 1); y_ = ysize * y; z_ = zsize * z; } if (e == 2){ x_ = xsize * x; y_ = ysize * (y + 1); z_ = zsize * z; } if (e == 3){ x_ = xsize * (x + 1); y_ = ysize * (y + 1); z_ = zsize * z; } if (e == 4){ x_ = xsize * x; y_ = ysize * y; z_ = zsize * (z + 1); } if (e == 5){ x_ = xsize * (x + 1); y_ = ysize * y; z_ = zsize * (z + 1); } if (e == 6){ x_ = xsize * x; y_ = ysize * (y + 1); z_ = zsize * (z + 1); } if (e == 7){ x_ = xsize * (x + 1); y_ = ysize * (y + 1); z_ = zsize * (z + 1); } Vector3DF yzMid[4]; yzMid[0] = eyebox[0] * x_ + eyebox[1] * (1.0f - x_); yzMid[1] = eyebox[2] * x_ + eyebox[3] * (1.0f - x_); yzMid[2] = eyebox[4] * x_ + eyebox[5] * (1.0f - x_); yzMid[3] = eyebox[6] * x_ + eyebox[7] * (1.0f - x_); Vector3DF zMid[2]; zMid[0] = yzMid[0] * y_ + yzMid[1] * (1.0f - y_); zMid[1] = yzMid[2] * y_ + yzMid[3] * (1.0f - y_); eyebox_[e] = zMid[0] * z_ + zMid[1] * (1.0f - z_); } Vector3DF max_(-FLT_MAX, -FLT_MAX, -FLT_MAX); Vector3DF min_(FLT_MAX, FLT_MAX, FLT_MAX); for (int32_t i = 0; i < 8; i++) { if (eyebox_[i].X > max_.X) max_.X = eyebox_[i].X; if (eyebox_[i].Y > max_.Y) max_.Y = eyebox_[i].Y; if (eyebox_[i].Z > max_.Z) max_.Z = eyebox_[i].Z; if (eyebox_[i].X < min_.X) min_.X = eyebox_[i].X; if (eyebox_[i].Y < min_.Y) min_.Y = eyebox_[i].Y; if (eyebox_[i].Z < min_.Z) min_.Z = eyebox_[i].Z; } ofs << x << "," << y << "," << z << std::endl; for (int32_t i = 0; i < 8; i++) { ofs << eyebox_[i].X << "," << eyebox_[i].Y << "," << eyebox_[i].Z << std::endl; } ofs << max_.X << "," << max_.Y << "," << max_.Z << std::endl; ofs << min_.X << "," << min_.Y << "," << min_.Z << std::endl; ofs << std::endl; } } } ofs << std::endl; /* レイヤー情報 */ ofs << layers.size() << std::endl; for (size_t i = 0; i < layers.size(); i++) { auto& layer = layers[i]; ofs << layer->GetGridXCount() << "," << layer->GetGridYCount() << "," << layer->GetGridZCount() << "," << layer->GetOffsetX() << "," << layer->GetOffsetY() << "," << layer->GetOffsetZ() << "," << layer->GetGridSize() << std::endl; for (size_t j = 0; j < layer->GetGrids().size(); j++) { auto& grid = layer->GetGrids()[j]; if (grid.GetObjects().size() > 0) { ofs << j << "," << grid.GetObjects().size() << std::endl; } } } Culling(cameraProjMat, isOpenGL); }