//=========================================== // Entity::setShape //=========================================== void Entity::setShape(std::unique_ptr<Shape> shape) { Range bounds = m_boundary; Shape* oldShape = m_shape ? dynamic_cast<Shape*>(m_shape->clone()) : NULL; float32_t oldRot_abs = getRotation_abs(); m_shape = std::move(shape); if (m_shape) { m_shape->rotate(m_rot); m_shape->scale(m_scale); m_shape->setLineWidth(m_lineWidth); m_shape->setFillColour(m_fillColour); m_shape->setLineColour(m_lineColour); } recomputeBoundary(); if (!m_silent) { EEvent* event1 = new EEntityBoundingBox(shared_from_this(), bounds, m_boundary); EEvent* event2 = new EEntityShape(shared_from_this(), pShape_t(oldShape), oldRot_abs, pShape_t(dynamic_cast<Shape*>(m_shape->clone())), getRotation_abs()); onEvent(event1); onEvent(event2); m_eventManager.queueEvent(event1); m_eventManager.queueEvent(event2); } }
//=========================================== // Entity::onParentTransformation //=========================================== void Entity::onParentTransformation(float32_t a, const Vec2f& s) { Range bounds = m_boundary; recomputeBoundary(); float32_t x = m_transl.x * cos(DEG_TO_RAD(a)) - m_transl.y * sin(DEG_TO_RAD(a)); float32_t y = m_transl.x * sin(DEG_TO_RAD(a)) + m_transl.y * cos(DEG_TO_RAD(a)); Vec2f oldTransl(x, y); Vec2f oldTransl_abs = s + oldTransl; float32_t oldRot_abs = a + m_rot; if (!m_silent) { float32_t rot_abs = getRotation_abs(); Vec2f transl_abs = getTranslation_abs(); EEvent* event1 = new EEntityBoundingBox(shared_from_this(), bounds, m_boundary); EEvent* event2 = new EEntityRotation(shared_from_this(), m_rot, oldRot_abs, m_rot, rot_abs); EEvent* event3 = new EEntityTranslation(shared_from_this(), m_transl, oldTransl_abs, m_transl, transl_abs); onEvent(event1); onEvent(event2); onEvent(event3); m_eventManager.queueEvent(event1); m_eventManager.queueEvent(event2); m_eventManager.queueEvent(event3); } for (set<pEntity_t>::iterator i = m_children.begin(); i != m_children.end(); ++i) (*i)->onParentTransformation(oldRot_abs, oldTransl_abs); }
//=========================================== // Entity::translate //=========================================== void Entity::translate(float32_t x, float32_t y) { Range bounds = m_boundary; float32_t oldRot = getRotation_abs(); Vec2f oldTransl = getTranslation_abs(); m_transl = m_transl + Vec2f(x, y); recomputeBoundary(); if (!m_silent) { Vec2f t = getTranslation_abs(); EEvent* event1 = new EEntityBoundingBox(shared_from_this(), bounds, m_boundary); EEvent* event2 = new EEntityTranslation(shared_from_this(), m_transl - Vec2f(x, y), oldTransl, m_transl, t); onEvent(event1); onEvent(event2); m_eventManager.queueEvent(event1); m_eventManager.queueEvent(event2); } for (set<pEntity_t>::iterator i = m_children.begin(); i != m_children.end(); ++i) (*i)->onParentTransformation(oldRot, oldTransl); }
void NIVissimConnectionCluster::removeConnections(const NodeSubCluster& c) { for (NodeSubCluster::ConnectionCont::const_iterator i = c.myConnections.begin(); i != c.myConnections.end(); i++) { NIVissimConnection* conn = *i; int connid = conn->getID(); std::vector<int>::iterator j = find(myConnections.begin(), myConnections.end(), connid); if (j != myConnections.end()) { myConnections.erase(j); } } recomputeBoundary(); }
//=========================================== // Entity::rotate // // Pivot is in model space //=========================================== void Entity::rotate(float32_t deg, const Vec2f& pivot) { float32_t oldRot = m_rot; float32_t oldRot_abs = getRotation_abs(); Vec2f oldTransl = m_transl; Vec2f oldTransl_abs = getTranslation_abs(); // - Find model's origin (bottom-left corner) in parent's model space (o) // - This is just m_transl (despite any prior rotations) // - Find pivot in parent's model space (p) // - p = (pivot rotated by m_rot) + o // - Compute value of o rotated about p by deg degrees // - Set m_transl to o // - Add deg to m_rot // Pivot in parent's model space (or world space if this is root) float32_t px = pivot.x * cos(DEG_TO_RAD(m_rot)) - pivot.y * sin(DEG_TO_RAD(m_rot)); float32_t py = pivot.x * sin(DEG_TO_RAD(m_rot)) + pivot.y * cos(DEG_TO_RAD(m_rot)); Vec2f p(px + m_transl.x, py + m_transl.y); // Rotate bottom-left corner around pivot Vec2f o = m_transl - p; o.x = o.x * cos(DEG_TO_RAD(deg)) - o.y * sin(DEG_TO_RAD(deg)); o.y = o.x * sin(DEG_TO_RAD(deg)) + o.y * cos(DEG_TO_RAD(deg)); m_transl.x = p.x + o.x; m_transl.y = p.y + o.y; m_rot += deg; rotateShapes_r(deg); Range bounds = m_boundary; recomputeBoundary(); Vec2f ds = m_transl - oldTransl; if (!m_silent) { EEvent* event1 = new EEntityBoundingBox(shared_from_this(), bounds, m_boundary); EEvent* event2 = new EEntityRotation(shared_from_this(), oldRot, oldRot_abs, m_rot, getRotation_abs()); EEvent* event3 = new EEntityTranslation(shared_from_this(), oldTransl, oldTransl_abs, m_transl, oldTransl_abs + ds); onEvent(event1); onEvent(event2); onEvent(event3); m_eventManager.queueEvent(event1); m_eventManager.queueEvent(event2); m_eventManager.queueEvent(event3); } for (set<pEntity_t>::iterator i = m_children.begin(); i != m_children.end(); ++i) (*i)->onParentTransformation(oldRot_abs, oldTransl_abs); }
NIVissimConnectionCluster::NIVissimConnectionCluster( const std::vector<int>& connections, const Boundary& boundary, int nodeCluster, const std::vector<int>& edges) : myConnections(connections), myBoundary(boundary), myNodeCluster(nodeCluster), myEdges(edges) { myClusters.push_back(this); recomputeBoundary(); assert(myBoundary.xmax() >= myBoundary.xmin()); // add information about incoming and outgoing edges for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) { NIVissimConnection* c = NIVissimConnection::dictionary(*i); assert(c != 0); myOutgoingEdges.push_back(c->getToEdgeID()); myIncomingEdges.push_back(c->getFromEdgeID()); assert(find(edges.begin(), edges.end(), c->getFromEdgeID()) != edges.end() || find(edges.begin(), edges.end(), c->getToEdgeID()) != edges.end()); } VectorHelper<int>::removeDouble(myIncomingEdges); VectorHelper<int>::removeDouble(myOutgoingEdges); }
// --------------------------------------------------------------------------- // NIVissimConnectionCluster - methods // --------------------------------------------------------------------------- NIVissimConnectionCluster::NIVissimConnectionCluster( const std::vector<int>& connections, int nodeCluster, int edgeid) : myConnections(connections), myNodeCluster(nodeCluster), myBlaID(myStaticBlaID++) { recomputeBoundary(); myClusters.push_back(this); assert(edgeid > 0); if (edgeid >= 0) { myEdges.push_back(edgeid); } // add information about incoming and outgoing edges for (std::vector<int>::const_iterator i = connections.begin(); i != connections.end(); i++) { NIVissimConnection* c = NIVissimConnection::dictionary(*i); assert(c != 0); myOutgoingEdges.push_back(c->getToEdgeID()); myIncomingEdges.push_back(c->getFromEdgeID()); assert(c->getFromEdgeID() == edgeid || c->getToEdgeID() == edgeid); } VectorHelper<int>::removeDouble(myIncomingEdges); VectorHelper<int>::removeDouble(myOutgoingEdges); }
//=========================================== // Entity::scale //=========================================== void Entity::scale(float32_t x, float32_t y) { Range bounds = m_boundary; pShape_t oldShape = m_shape ? pShape_t(dynamic_cast<Shape*>(m_shape->clone())) : pShape_t(); float32_t oldRot_abs = getRotation_abs(); if (m_shape) m_shape->scale(Vec2f(x, y)); m_scale.x *= x; m_scale.y *= y; recomputeBoundary(); if (!m_silent) { EEvent* event1 = new EEntityBoundingBox(shared_from_this(), bounds, m_boundary); EEvent* event2 = new EEntityShape(shared_from_this(), oldShape, oldRot_abs, pShape_t(m_shape ? dynamic_cast<Shape*>(m_shape->clone()) : NULL), getRotation_abs()); onEvent(event1); onEvent(event2); m_eventManager.queueEvent(event1); m_eventManager.queueEvent(event2); } }
//=========================================== // Entity::setParent //=========================================== void Entity::setParent(Entity* parent) { Entity* oldParent = m_parent; if (m_parent) m_parent->removeChild(shared_from_this()); m_parent = parent; m_parent->m_children.insert(shared_from_this()); rotateShapes_r(m_parent->getRotation_abs()); onParentTransformation(oldParent ? oldParent->getRotation_abs() : 0.f, oldParent ? oldParent->getTranslation_abs() : Vec2f(0.f, 0.f)); Range bounds = m_boundary; recomputeBoundary(); if (!m_silent) { EEvent* event1 = new EEntityBoundingBox(shared_from_this(), bounds, m_boundary); onEvent(event1); m_eventManager.queueEvent(event1); } }
//=========================================== // Entity::Entity //=========================================== Entity::Entity(const XmlNode data) : Asset(internString("Entity")), m_silent(false), m_parent(NULL) { AssetManager assetManager; ShapeFactory shapeFactory; try { setSilent(true); XML_NODE_CHECK(data, Entity); XmlAttribute attr = data.firstAttribute(); XML_ATTR_CHECK(attr, type); m_type = internString(attr.getString()); attr = attr.nextAttribute(); XML_ATTR_CHECK(attr, name); m_name = internString(attr.getString()); attr = attr.nextAttribute(); XML_ATTR_CHECK(attr, x); m_transl.x = attr.getFloat(); attr = attr.nextAttribute(); XML_ATTR_CHECK(attr, y); m_transl.y = attr.getFloat(); attr = attr.nextAttribute(); XML_ATTR_CHECK(attr, z); m_z = attr.getFloat(); // So that no Z values are 'exactly' equal m_z += 0.1f * static_cast<float32_t>(rand()) / static_cast<float32_t>(RAND_MAX); attr = attr.nextAttribute(); XML_ATTR_CHECK(attr, rot); float32_t rot = attr.getFloat(); XmlNode node = data.firstChild(); if (!node.isNull() && node.name() == "shape") { m_shape = unique_ptr<Shape>(shapeFactory.create(node.firstChild())); node = node.nextSibling(); } m_rot = 0; setRotation(rot); XML_NODE_CHECK(node, scale); m_scale = Vec2f(1.f, 1.f); setScale(Vec2f(node.firstChild())); node = node.nextSibling(); XML_NODE_CHECK(node, fillColour); m_fillColour = Colour(node.firstChild()); node = node.nextSibling(); XML_NODE_CHECK(node, lineColour); m_lineColour = Colour(node.firstChild()); node = node.nextSibling(); XML_NODE_CHECK(node, lineWidth); m_lineWidth = node.getInt(); node = node.nextSibling(); XML_NODE_CHECK(node, children); XmlNode node_ = node.firstChild(); while (!node_.isNull() && node_.name() == "child") { XmlAttribute attr = node_.firstAttribute(); if (!attr.isNull() && attr.name() == "ptr") { long id = attr.getLong(); pEntity_t child = boost::dynamic_pointer_cast<Entity>(assetManager.getAssetPointer(id)); if (!child) throw XmlException("Bad entity asset id", __FILE__, __LINE__); addChild(child); } node_ = node_.nextSibling(); } setSilent(false); ++m_count; } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class Entity; "); throw; } recomputeBoundary(); }
//=========================================== // Entity::assignData //=========================================== void Entity::assignData(const XmlNode data) { if (data.isNull() || data.name() != "Entity") return; AssetManager assetManager; ShapeFactory shapeFactory; try { bool silent = isSilent(); setSilent(true); XmlAttribute attr = data.firstAttribute(); if (!attr.isNull() && attr.name() == "type") { m_type = internString(attr.getString()); attr = attr.nextAttribute(); } if (!attr.isNull() && attr.name() == "name") { m_name = internString(attr.getString()); attr = attr.nextAttribute(); } Vec2f transl = m_transl; if (!attr.isNull() && attr.name() == "x") { transl.x = attr.getFloat(); attr = attr.nextAttribute(); } if (!attr.isNull() && attr.name() == "y") { transl.y = attr.getFloat(); attr = attr.nextAttribute(); } setTranslation(transl); if (!attr.isNull() && attr.name() == "z") { m_z = attr.getFloat(); // So that no Z values are 'exactly' equal m_z += 0.1f * static_cast<float32_t>(rand()) / static_cast<float32_t>(RAND_MAX); attr = attr.nextAttribute(); } XmlNode node = data.firstChild(); if (!node.isNull() && node.name() == "shape") { m_shape = unique_ptr<Shape>(shapeFactory.create(node.firstChild())); node = node.nextSibling(); } if (!node.isNull() && node.name() == "scale") { setScale(Vec2f(node.firstChild())); node = node.nextSibling(); } if (!attr.isNull() && attr.name() == "rot") { setRotation(attr.getFloat()); } if (!node.isNull() && node.name() == "fillColour") { m_fillColour = Colour(node.firstChild()); node = node.nextSibling(); } if (!node.isNull() && node.name() == "lineColour") { m_lineColour = Colour(node.firstChild()); node = node.nextSibling(); } if (!node.isNull() && node.name() == "lineWidth") { m_lineWidth = node.getInt(); node = node.nextSibling(); } if (!node.isNull() && node.name() == "children") { XmlNode node_ = node.firstChild(); while (!node_.isNull() && node_.name() == "child") { XmlAttribute attr = node_.firstAttribute(); if (!attr.isNull() && attr.name() == "ptr") { long id = attr.getLong(); pEntity_t child = boost::dynamic_pointer_cast<Entity>(assetManager.getAssetPointer(id)); if (!child) throw XmlException("Bad entity asset id", __FILE__, __LINE__); addChild(child); } node_ = node_.nextSibling(); } } setSilent(silent); } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class Entity; "); throw; } recomputeBoundary(); }