void QtGraphicsViewVisitor::drawBoundingBox(BoundingBox &boundingBox) {
    int x = boundingBox.getX();
    int y = boundingBox.getY();
    int w = boundingBox.getWidth();
    int h = boundingBox.getHeight();
    scene->addRect(x, y, w, h, *greenPen);
}
예제 #2
0
bool BoundingBox::overlapsWith(const BoundingBox& other)
{
   if(!use || !other.use) return false;

   float wa = getWidth()/2;
   float ha = getHeight()/2;
   float da = getDepth()/2;

   glm::vec3 Ca = getCenter();
   glm::vec3 Az = getFrontNormal();
   glm::vec3 Ay = getUpNormal();
   glm::vec3 Ax = getRightNormal();

   glm::vec3 Cb = other.getCenter();
   glm::vec3 Bz = other.getFrontNormal();
   glm::vec3 By = other.getUpNormal();
   glm::vec3 Bx = other.getRightNormal();
   float wb = other.getWidth()/2;
   float hb = other.getHeight()/2;
   float db = other.getDepth()/2;

   glm::vec3 T = Cb - Ca;

   float lhs = 0, rhs = 0;

   float Rxx = glm::dot(Ax, Bx);
   float Rxy = glm::dot(Ax, By);
   float Rxz = glm::dot(Ax, Bz);

   // Case 1: L = Ax
   lhs = glm::dot(T, Ax);
   rhs = wa + fabs(wb * Rxx) + fabs(hb * Rxy) + fabs(db * Rxz);
   if(lhs > rhs) return false;

   float Ryx = glm::dot(Ay, Bx);
   float Ryy = glm::dot(Ay, By);
   float Ryz = glm::dot(Ay, Bz);

   // Case 2: L = Ay
   lhs = glm::dot(T, Ay);
   rhs = ha + fabs(wb * Ryx) + fabs(hb * Ryy) + fabs(db * Ryz);
   if(lhs > rhs) return false;

   float Rzx = glm::dot(Az, Bx);
   float Rzy = glm::dot(Az, By);
   float Rzz = glm::dot(Az, Bz);

   // Case 3: L = Az
   lhs = glm::dot(T, Az);
   rhs = da + fabs(wb * Rzx) + fabs(hb * Rzy) + fabs(db * Rzz);
   if(lhs > rhs) return false;

   // Case 4: L = Bx
   lhs = glm::dot(T, Bx);
   rhs = fabs(wa * Rxx) + fabs(ha * Ryx) + fabs(da * Rzx) + wb;
   if(lhs > rhs) return false;

   // Case 5: L = By
   lhs = glm::dot(T, By);
   rhs = fabs(wa * Rxy) + fabs(ha * Ryy) + fabs(da * Rzy) + hb;
   if(lhs > rhs) return false;

   // Case 6: L = Bz
   lhs = glm::dot(T, Bz);
   rhs = fabs(wa * Rxz) + fabs(ha * Ryz) + fabs(da * Rzz) + db;
   if(lhs > rhs) return false;

   // Case 7: L = Ax x Bx
   lhs = glm::dot(T, glm::cross(Ax, Bx));
   rhs = fabs(ha * Rzx) + fabs(da * Ryx) + fabs(hb * Rxz) + fabs(db * Rxy);
   if(lhs > rhs) return false;

   // Case 8: L = Ax x By
   lhs = glm::dot(T, glm::cross(Ax, By));
   rhs = fabs(ha * Rzy) + fabs(da * Ryy) + fabs(wb * Rxz) + fabs(db * Rxx);
   if(lhs > rhs) return false;

   // Case 9: L = Ax x Bz
   lhs = glm::dot(T, glm::cross(Ax, Bz));
   rhs = fabs(ha * Rzz) + fabs(da * Ryz) + fabs(wb * Rxy) + fabs(hb * Rxx);
   if(lhs > rhs) return false;

   // Case 10: L = Ay x Bx
   lhs = glm::dot(T, glm::cross(Ay, Bx));
   rhs = fabs(wa * Rzx) + fabs(da * Rxx) + fabs(hb * Ryz) + fabs(db * Ryy);
   if(lhs > rhs) return false;

   // Case 11: L = Ay x By
   lhs = glm::dot(T, glm::cross(Ay, By));
   rhs = fabs(wa * Rzy) + fabs(da * Rxy) + fabs(wb * Ryz) + fabs(db * Ryx);
   if(lhs > rhs) return false;

   // Case 12: L = Ay x Bz
   lhs = glm::dot(T, glm::cross(Ay, Bz));
   rhs = fabs(wa * Rzz) + fabs(da * Rxz) + fabs(wb * Ryy) + fabs(hb * Ryx);
   if(lhs > rhs) return false;

   // Case 13: L = Az x Bx
   lhs = glm::dot(T, glm::cross(Az, Bx));
   rhs = fabs(wa * Ryx) + fabs(ha * Rxx) + fabs(hb * Rzz) + fabs(db * Rzy);
   if(lhs > rhs) return false;

   // Case 14: L = Az x By
   lhs = glm::dot(T, glm::cross(Az, By));
   rhs = fabs(wa * Ryy) + fabs(ha * Rxy) + fabs(wb * Rzz) + fabs(db * Rzx);
   if(lhs > rhs) return false;

   // Case 15: L = Az x Bz
   lhs = glm::dot(T, glm::cross(Az, Bz));
   rhs = fabs(wa * Ryz) + fabs(ha * Rxz) + fabs(wb * Rzy) + fabs(hb * Rzx);
   if(lhs > rhs) return false;

   return true;
}
예제 #3
0
osg::Drawable *ClampNode::createBrick(void) const {
    // Get the brick
    Clamp* clamp = static_cast<Clamp*>(_lego);
    
    // Get brick color
    QColor color = clamp->getColor();

    // Get clamp bounding box
    clamp->calculateBoundingBox();
    BoundingBox bb = clamp->getBoundingBox();
    // Get integer sizes
    int width = bb.getWidth();
    int length = bb.getLength();
    int height = bb.getHeight();

    // Get real position, according to tile size
    double mw = (-width)*Lego::length_unit/2;
    double mwpm = (-width)*Lego::length_unit/2+Lego::height_unit/2;
    double mwp = (-width)*Lego::length_unit/2+0.93*Lego::height_unit;
    double pw = (width)*Lego::length_unit/2;
    double pwm = (width)*Lego::length_unit/2-Lego::height_unit/2;
    double ml = (-length)*Lego::length_unit/2;
    double mlp = (-length+0.5)*Lego::length_unit/2;
    double pl = (length)*Lego::length_unit/2;
    double plm = (length-0.5)*Lego::length_unit/2;
    double mh = (-height)*Lego::height_unit/2;
    double mhp = (-height)*Lego::height_unit/2+2*Lego::plot_top_height;
    double mhpm = (-height)*Lego::height_unit/2+Lego::plot_top_height;
    double phm = (height)*Lego::height_unit/2-Lego::height_unit/2;
    double phmp = (height)*Lego::height_unit/2-0.5*Lego::height_unit/2;
    
    // Create 3 vertices
    osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
    osg::Vec3 v0(ml, mw, mh);
    osg::Vec3 v1(pl, mw, mh);
    osg::Vec3 v2(pl, pw, mh);
    osg::Vec3 v3(ml, pw, mh);
    osg::Vec3 v4(ml, pw, mhp);
    osg::Vec3 v5(pl, pw, mhp);
    osg::Vec3 v6(pl, mw, mhp);
    osg::Vec3 v7(ml, mw, mhp);
    osg::Vec3 v8(mlp, mw, mhp);
    osg::Vec3 v9(mlp, mw, phm);
    osg::Vec3 v10(ml, mw, phm);
    osg::Vec3 v11(ml, mwp, phmp);
    osg::Vec3 v12(mlp, mwp, phmp);
    osg::Vec3 v13(mlp, pw, mhp);
    osg::Vec3 v14(plm, mw, mhp);
    osg::Vec3 v15(plm, mw, phm);
    osg::Vec3 v16(pl, mw, phm);
    osg::Vec3 v17(pl, mwp, phmp);
    osg::Vec3 v18(plm, mwp, phmp);
    osg::Vec3 v19(plm, pw, mhp);
    osg::Vec3 v20(mlp, mwpm, mh);
    osg::Vec3 v21(plm, mwpm, mh);
    osg::Vec3 v22(plm, pwm, mh);
    osg::Vec3 v23(mlp, pwm, mh);
    osg::Vec3 v24(mlp, mwpm, mhpm);
    osg::Vec3 v25(plm, mwpm, mhpm);
    osg::Vec3 v26(plm, pwm, mhpm);
    osg::Vec3 v27(mlp, pwm, mhpm);
    
    // Create 1 faces, 0 faces are quads splitted into two triangles
    // NB: Down face is transparent, we don't even create it

    // Bottom
    vertices->push_back(v3);
    vertices->push_back(v2);
    vertices->push_back(v1);
    vertices->push_back(v0);
    // Bottom hole
    vertices->push_back(v20);
    vertices->push_back(v21);
    vertices->push_back(v22);
    vertices->push_back(v23);
    // Bottom far
    vertices->push_back(v24);
    vertices->push_back(v25);
    vertices->push_back(v26);
    vertices->push_back(v27);

    // Front face
    vertices->push_back(v2);
    vertices->push_back(v3);
    vertices->push_back(v4);
    vertices->push_back(v5);

    // Back face
    vertices->push_back(v0);
    vertices->push_back(v1);
    vertices->push_back(v6);
    vertices->push_back(v7);

    // Left bottom face
    vertices->push_back(v0);
    vertices->push_back(v3);
    vertices->push_back(v4);
    vertices->push_back(v7);

    // Right bottom face
    vertices->push_back(v1);
    vertices->push_back(v2);
    vertices->push_back(v5);
    vertices->push_back(v6);

    // Top face
    vertices->push_back(v4);
    vertices->push_back(v5);
    vertices->push_back(v6);
    vertices->push_back(v7);

    // Left part back
    vertices->push_back(v7);
    vertices->push_back(v8);
    vertices->push_back(v9);
    vertices->push_back(v10);

    // Left part left ext
    vertices->push_back(v4);
    vertices->push_back(v7);
    vertices->push_back(v10);
    vertices->push_back(v11);

    // Left part front
    vertices->push_back(v4);
    vertices->push_back(v11);
    vertices->push_back(v12);
    vertices->push_back(v13);

    // Left part left int
    vertices->push_back(v8);
    vertices->push_back(v9);
    vertices->push_back(v12);
    vertices->push_back(v13);

    // Right part back
    vertices->push_back(v6);
    vertices->push_back(v14);
    vertices->push_back(v15);
    vertices->push_back(v16);

    // Left part left ext
    vertices->push_back(v5);
    vertices->push_back(v6);
    vertices->push_back(v16);
    vertices->push_back(v17);

    // Left part front
    vertices->push_back(v5);
    vertices->push_back(v17);
    vertices->push_back(v18);
    vertices->push_back(v19);

    // Left part left int
    vertices->push_back(v14);
    vertices->push_back(v15);
    vertices->push_back(v18);
    vertices->push_back(v19);

    // Bottom front
    vertices->push_back(v20);
    vertices->push_back(v21);
    vertices->push_back(v25);
    vertices->push_back(v24);

    // Bottom right
    vertices->push_back(v21);
    vertices->push_back(v22);
    vertices->push_back(v26);
    vertices->push_back(v25);

    // Bottom back
    vertices->push_back(v22);
    vertices->push_back(v23);
    vertices->push_back(v27);
    vertices->push_back(v26);

    // Bottom left
    vertices->push_back(v23);
    vertices->push_back(v20);
    vertices->push_back(v24);
    vertices->push_back(v27);

    // Create tile geometry
    osg::ref_ptr<osg::Geometry> clampGeometry = new osg::Geometry;
    
    // Match vertices
    clampGeometry->setVertexArray(vertices);
    
    // Create colors
    osg::Vec4 osgColor(static_cast<float>(color.red())/255.0, static_cast<float>(color.green())/255.0, static_cast<float>(color.blue())/255.0, 1.0);
    osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
    // Every face has the same color, so there is only one color
    colors->push_back(osgColor);
    
    // Match color
    clampGeometry->setColorArray(colors);
    clampGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
    
    // Create normals
    osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
    normals->push_back(osg::Vec3(0, 0, -1));
    normals->push_back(osg::Vec3(0, 0, -1));
    normals->push_back(osg::Vec3(0, 1, 0));
    normals->push_back(osg::Vec3(0, -1, 0));
    normals->push_back(osg::Vec3(-1, 0, 0));
    normals->push_back(osg::Vec3(1, 0, 0));
    normals->push_back(osg::Vec3(0, 0, 1));
    normals->push_back(osg::Vec3(0, -1, 0));
    normals->push_back(osg::Vec3(-1, 0, 0));
    double w = pw - mwp;
    double h = phmp - mhp;
    double norm = std::sqrt(w*w + h*h);
    normals->push_back(osg::Vec3(0, h/norm, w/norm));
    normals->push_back(osg::Vec3(1, 0, 0));
    normals->push_back(osg::Vec3(0, -1, 0));
    normals->push_back(osg::Vec3(1, 0, 0));
    normals->push_back(osg::Vec3(0, h/norm, w/norm));
    normals->push_back(osg::Vec3(-1, 0, 0));
    normals->push_back(osg::Vec3(0, 1, 0));
    normals->push_back(osg::Vec3(-1, 0, 0));
    normals->push_back(osg::Vec3(0, -1, 0));
    normals->push_back(osg::Vec3(1, 0, 0));
    
    // Match normals
    clampGeometry->setNormalArray(normals);
    clampGeometry->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);

    // Define 1 GL_QUADS with 1*4 vertices, corresponding to bottom part
    clampGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0*4, 4));

    // Define 1 GL_QUADS with 1*4 vertices, corresponding to 1 hole in bottom part
    clampGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 1*4, 4));

    // Retesslate to create hole
    osgUtil::Tessellator tesslator;
    tesslator.setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY);
    tesslator.setWindingType(osgUtil::Tessellator::TESS_WINDING_ODD);
    tesslator.retessellatePolygons(*clampGeometry);

    // Create 17 GL_QUADS, i.e. 18*4 vertices
    clampGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 2*4, 18*4));

    // Return the tile whithout plot
    return clampGeometry.release();
}
예제 #4
0
void ClampNode::createGeode(void) {
    // Remove children
    removeChildren(0, getNumChildren());
    
    // Create geode
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    addChild(geode);
    geode->addDrawable(createBrick());

    // Distance between two plot center
    double distPlot = Lego::length_unit;

    // Get the brick
    Clamp* clamp = static_cast<Clamp*>(_lego);

    // Get clamp bounding box
    clamp->calculateBoundingBox();
    BoundingBox bb = clamp->getBoundingBox();
    // Get integer sizes
    int width = bb.getWidth();
    int length = bb.getLength();
    int height = bb.getHeight();

    // Calculate x max and y max for plots
    double xminb = -(length-2)*Lego::length_unit/2;
    double yminb = -(width-1)*Lego::length_unit/2;

    double w = (-width)*Lego::length_unit/2+Lego::height_unit/2;
    double h = (height)*Lego::height_unit/2-Lego::height_unit/2;

    // Add cylinder parts

    // Create geode
    osg::ref_ptr<osg::Geode> cylinderGeode = new osg::Geode;

    // Create drawable cylinder
    osg::Drawable* cylinderPart = makeCylinder(0, w, h, length*Lego::length_unit, Lego::height_unit/2);
    // Add drawable to geode
    cylinderGeode->addDrawable(cylinderPart);

    // Create top and bottom cylinder
    osg::Drawable* topPart = makeDisk(0, w, h, Lego::height_unit/2, length*Lego::length_unit, true);
    osg::Drawable* bottomPart = makeDisk(0, w, h, Lego::height_unit/2, length*Lego::length_unit, false);
    // Add drawables to geode
    cylinderGeode->addDrawable(topPart);
    cylinderGeode->addDrawable(bottomPart);

    // Create matrix transform to rotate cylinder
    osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
    // Create matrix to handle rotation
    osg::Matrix matRot, matTrans;
    // Make PI/2 rotation according to y axis
    matRot.makeRotate(M_PI_2, osg::Vec3(0.f, 1.f, 0.f));
    // Translate
    matTrans.makeTranslate(-length*Lego::length_unit/4-Lego::height_unit/4, 0, 3*height*Lego::height_unit/8);
    // Set matrix transform matrix
    mt->setMatrix(matRot*matTrans);
    // Add geode to matrix transform
    mt->addChild(cylinderGeode.get());
    // Add matrix transform
    addChild(mt);

    // Add bottom cylinders iteratively
    for (int i = 0; i < length-1; i++) {
        for (int j = 0; j < width; j++) {
            double radiusX = xminb + i*distPlot;
            double radiusY = yminb + j*distPlot;

            addChild(createBottomCylinder(radiusX, radiusY, 0.5, true, (-height+0.5)*Lego::height_unit/2));
        }
    }
}