void update(const T& data) { XY_ASSERT(m_id, "No valid UBO ID found"); { XY_ASSERT(m_typeIndex == typeid(T).hash_code(), "Cannot update UBO with data of this type"); { glCheck(glBindBuffer(GL_UNIFORM_BUFFER, m_id)); GLvoid* ptr; glCheck(ptr = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY)); std::memcpy(ptr, &data, sizeof(T)); glCheck(glUnmapBuffer(GL_UNIFORM_BUFFER)); } } }
void VacuumController::onStart(xy::Entity& entity) { m_model = entity.getComponent<xy::Model>(); XY_ASSERT(m_model, "entity has no model!"); m_initialPosition = m_model->getPosition(); auto audio = entity.getComponents<xy::AudioSource>(); m_audioLoop = audio[0]; }
void UserInterface::removeItems(const void* owner) { XY_ASSERT(owner, "don't do this!"); items.erase(std::remove_if(items.begin(), items.end(), [owner](const Item& item) { return item.owner == owner; }), items.end()); }
/*! \brief Constructor. \param size Maximum number of objects to store in the pool */ explicit ObjectPool(std::size_t size) : m_poolBuffer (size * sizeof(T)), m_slots (size), m_firstFreeIndex(0) { XY_ASSERT(size < MAX_BUFFER_SIZE, "max pool size is 2048 objects"); auto stride = sizeof(T); for (auto i = 0u; i < size; ++i) { m_slots[i] = std::make_pair(reinterpret_cast<T*>(m_poolBuffer.data() + (i * stride)), true); } }
void HatSystem::destroy(xy::Entity entity) { XY_ASSERT(entity.hasComponent<MagicHat>(), "Not a hat entity"); const auto& tx = entity.getComponent<xy::Transform>(); getScene()->destroyEntity(entity); //broadcast to client ActorEvent evt; evt.actor.id = entity.getIndex(); evt.actor.type = entity.getComponent<Actor>().type; evt.x = tx.getPosition().x; evt.y = tx.getPosition().y; evt.type = ActorEvent::Died; m_host.broadcastPacket(PacketID::ActorEvent, evt, xy::NetFlag::Reliable, 1); }
/*! \brief Returns a given vector with its length normalized to 1 */ static inline sf::Vector2f normalise(sf::Vector2f source) { float length = std::sqrt(dot(source, source)); XY_ASSERT(length != 0, "Division by zero"); return source /= length; }
xy::Entity::Ptr TrackSection::create(xy::MessageBus& mb, float height) { XY_ASSERT(!m_uids.empty(), "parts not yet cached!"); auto body = xy::Component::create<xy::Physics::RigidBody>(mb, xy::Physics::BodyType::Kinematic); xy::Physics::CollisionFilter cf; cf.categoryFlags |= PhysCat::Wall; cf.maskFlags |= PhysCat::SmallBody; auto uid = m_uids[m_index].id; //top two points of centre part sf::Vector2f tl(sectionSize, connectionHeight); sf::Vector2f tr(0.f, connectionHeight); //upper half of ID represents top 3 connections auto bits = uid & 0xf; XY_ASSERT(bits != 0 && bits != 0x8, "can't have empty segments"); if (bits & 0x4) { //top left xy::Physics::CollisionEdgeShape es(connections[0].first); es.setFilter(cf); body->addCollisionShape(es); es.setPoints(connections[0].second); body->addCollisionShape(es); if (tl.x > 0.f) tl.x = 0.f; if (tr.x < connectionWidth + connectionGap) tr.x = connectionWidth + connectionGap; } if (bits & 0x2) { //top middle xy::Physics::CollisionEdgeShape es(connections[1].first); es.setFilter(cf); body->addCollisionShape(es); es.setPoints(connections[1].second); body->addCollisionShape(es); if (tl.x > connectionWidth + connectionGap) tl.x = connectionWidth + connectionGap; if (tr.x < (connectionWidth * 2.f) + connectionGap) tr.x = (connectionWidth * 2.f) + connectionGap; } if (bits & 0x1) { //top right xy::Physics::CollisionEdgeShape es(connections[2].first); es.setFilter(cf); body->addCollisionShape(es); es.setPoints(connections[2].second); body->addCollisionShape(es); if (tl.x >(connectionWidth * 2.f) + connectionGap) tl.x = (connectionWidth * 2.f) + connectionGap; if (tr.x < sectionSize) tr.x = sectionSize; } if (bits == (0x4 | 0x1)) { //we have left and right but no middle xy::Physics::CollisionEdgeShape es( { sf::Vector2f(connectionWidth + connectionGap, connectionHeight), sf::Vector2f(sectionSize / 2.f, connectionHeight + 30.f), //just enough to prevent squashed balls sf::Vector2f((connectionWidth * 2.f) + connectionGap, connectionHeight) }); es.setFilter(cf); body->addCollisionShape(es); } //bottom two points of centre part sf::Vector2f bl(sectionSize, connectionHeight * 3.f); sf::Vector2f br(0.f, connectionHeight * 3.f); //else bottom 3 bits = (uid & 0xf0) >> 4; XY_ASSERT(bits != 0 && bits != 0x8, "can't have empty segments"); if (bits & 0x4) { //bottom left xy::Physics::CollisionEdgeShape es(connections[3].first); es.setFilter(cf); body->addCollisionShape(es); es.setPoints(connections[3].second); body->addCollisionShape(es); if (bl.x > 0.f) bl.x = 0.f; if (br.x < connectionWidth + connectionGap) br.x = connectionWidth + connectionGap; } if (bits & 0x2) { //bottom middle xy::Physics::CollisionEdgeShape es(connections[4].first); es.setFilter(cf); body->addCollisionShape(es); es.setPoints(connections[4].second); body->addCollisionShape(es); if (bl.x > connectionWidth + connectionGap) bl.x = connectionWidth + connectionGap; if (br.x < (connectionWidth * 2.f) + connectionGap) br.x = (connectionWidth * 2.f) + connectionGap; } if (bits & 0x1) { //bottom right xy::Physics::CollisionEdgeShape es(connections[5].first); es.setFilter(cf); body->addCollisionShape(es); es.setPoints(connections[5].second); body->addCollisionShape(es); if (bl.x >(connectionWidth * 2.f) + connectionGap) bl.x = (connectionWidth * 2.f) + connectionGap; if (br.x < sectionSize) br.x = sectionSize; } if (bits == (0x4 | 0x1)) { //we have left and right but no middle xy::Physics::CollisionEdgeShape es({ sf::Vector2f(connectionWidth + connectionGap, sectionSize - connectionHeight), sf::Vector2f((connectionWidth * 2.f) + connectionGap, sectionSize - connectionHeight) }); es.setFilter(cf); body->addCollisionShape(es); } //create centre part xy::Physics::CollisionEdgeShape es({ tl, bl }); es.setFilter(cf); body->addCollisionShape(es); es.setPoints({ tr, br }); body->addCollisionShape(es); body->setLinearVelocity({ 0.f, m_initialVelocity }); auto controller = xy::Component::create<SectionController>(mb, *this); auto model = m_meshRenderer.createModel(uid, mb); if (m_trackMaterial) { for (auto i = 0u; i < m_uids[m_index].barrierOffset; ++i) { model->setSubMaterial(*m_trackMaterial, i); } } if (m_barrierMaterial) { for (auto i = m_uids[m_index].barrierOffset; i < model->getMesh().getSubMeshCount(); ++i) { model->setSubMaterial(*m_barrierMaterial, i); } } auto entity = xy::Entity::create(mb); entity->setPosition((xy::DefaultSceneSize.x - sectionSize) / 2.f, height); entity->addComponent(body); entity->addComponent(controller); entity->addComponent(model); m_index = (m_index + 1) % m_uids.size(); //remember to do this as late as possible return std::move(entity); }