std::vector<Entity> VoxelShredder::explode(Entity & originalEntity) { std::vector<Entity> segmentEntities; auto origin = originalEntity.component<Transform3DComponent>().transform().position(); VoxelShredder shredder; auto entities = shredder.shred(originalEntity); for (auto & entity : entities) { auto & object = entity.component<VoxelObject>(); auto & originalVoxelData = object.data(); auto & splitDetector = object.data()->splitDetector(); object.performSplitDetection(); const auto & segments = splitDetector.segments(); AssertM( !segments.empty() || originalVoxelData->numVoxels() == 0, entity.name() + ": there has to be one split, the object itself, by " "definition. " "Remaining voxels: " + std::to_string(originalVoxelData->numVoxels())); if (segments.size() <= 1) { segmentEntities.emplace_back(entity); continue; } for (size_t s = 0; s < segments.size(); s++) { auto entity2 = VoxelClusterSplitSystem::splitVoxelsOffEntity(entity, segments[s]); segmentEntities.emplace_back(entity2); } entity.scheduleRemoval(); } // Apply explosive forces for (auto & entity : segmentEntities) { auto & body = entity.component<RigidBodyComponent>().value(); body->adaptShape(); const auto direction = GLMSafeNormalize(body->transform().position() - origin); const auto intensity = RandomFloat(750.0f, 1800.0f) * body->mass() / 4.0f; body->applyCentralImpulse(direction * intensity); body->applyTorqueImpulse(0.008f * RandomVec3(1.0f, 2.0f) * intensity); body->setDamping(0.4f, 0.2f); } originalEntity.scheduleRemoval(); return segmentEntities; }
void SceneGroup::Update() { cnt++; if(cnt%25==0) { Vec3 start_pos = RandomVec3(Vec3(-220, -220, 250), Vec3(220, 220, 280)); Vec3 start_speed = RandomVec3(Vec3(-0.2, -0.2, 0), Vec3(0.2, 0.2, 0)); AddBomb(start_pos, start_speed); if(cnt%(3*25)==0 && !GameOver()) { Vec3 player_pos = Vec3(0,0,0) * player_matrix->getMatrix() + Vec3(0,0,250); AddBomb(player_pos, Vec3(0,0,0)); } } std::list<Bomb*>::iterator iter; for(iter = bomb_list.begin(); iter!=bomb_list.end();) { if(CollideWithScene(*iter)) { if(!GameOver() && CollideWithPlayer(*iter)) { hurt_cnt = 60; health_num -=3; } remove_list.push(*iter); iter = bomb_list.erase(iter); } else { iter++; } } if(hurt_cnt > 0 && hurt==false) { hurt = true; player_matrix->getOrCreateStateSet()->setAttributeAndModes(program_red, StateAttribute::Values::ON); } else if(hurt_cnt == 0 && hurt == true) { hurt = false; player_matrix->getOrCreateStateSet()->setAttributeAndModes(program_normal, StateAttribute::Values::ON); } if(hurt_cnt > 0) hurt_cnt--; s_stream.clear(); for(int i=1; i<=health_num; i++) { s_stream<<(char)(3); } std::string health_text; s_stream>>health_text; health->setText(health_text); if(GameOver()) { player_matrix->setNodeMask(0); } else { std::string score_text; s_stream.clear(); s_stream<<"Score: "<<(cnt/10); s_stream>>score_text; score->setText(score_text); } while(!remove_list.empty()) { Entity* now_node = remove_list.front(); remove_list.pop(); scene_root->removeChild(now_node); } }