Ejemplo n.º 1
0
//=====================================================================
bool MouseBoxZoomer::eventFilter(QObject *widget, QEvent *e) {
  GlMainWidget *glw = static_cast<GlMainWidget *>(widget);
  GlGraphInputData *inputData = glw->getScene()->getGlGraphComposite()->getInputData();

  if (e->type() == QEvent::MouseButtonPress) {
    QMouseEvent * qMouseEv = static_cast<QMouseEvent *>(e);

    if (qMouseEv->buttons() == mButton &&
        (kModifier == Qt::NoModifier ||
         qMouseEv->modifiers() & kModifier)) {
      if (!started) {
        x = qMouseEv->x();
        y =  glw->height() - qMouseEv->y();
        w = 0;
        h = 0;
        started = true;
        graph = inputData->getGraph();
      }
      else {
        if (inputData->getGraph() != graph) {
          graph = NULL;
          started = false;
        }
      }

      return true;
    }

    if (qMouseEv->buttons()==Qt::MidButton) {
      started = false;
      glw->redraw();
      return true;
    }

    return false;
  }

  if (e->type() == QEvent::MouseMove) {
    QMouseEvent * qMouseEv = static_cast<QMouseEvent *>(e);

    if ((qMouseEv->buttons() & mButton) &&
        (kModifier == Qt::NoModifier ||
         qMouseEv->modifiers() & kModifier)) {
      if (inputData->getGraph() != graph) {
        graph = NULL;
        started = false;
      }

      if (started) {
        if ((qMouseEv->x() > 0) && (qMouseEv->x() < glw->width()))
          w = qMouseEv->x() - x;

        if ((qMouseEv->y() > 0) && (qMouseEv->y() < glw->height()))
          h = y - (glw->height() - qMouseEv->y());

        glw->redraw();
        return true;
      }
    }
  }

  if (e->type() == QEvent::MouseButtonDblClick) {
    GlBoundingBoxSceneVisitor bbVisitor(inputData);
    glw->getScene()->getLayer("Main")->acceptVisitor(&bbVisitor);
    QtGlSceneZoomAndPanAnimator zoomAnPan(glw, bbVisitor.getBoundingBox());
    zoomAnPan.animateZoomAndPan();
    return true;
  }

  if (e->type() == QEvent::MouseButtonRelease) {

    QMouseEvent * qMouseEv = static_cast<QMouseEvent *>(e);

    if ((qMouseEv->button() == mButton &&
         (kModifier == Qt::NoModifier ||
          qMouseEv->modifiers() & kModifier))) {
      if (inputData->getGraph() != graph) {
        graph = NULL;
        started = false;
      }

      if (started) {
        started = false;

        if(!(w==0 && h==0)) {
          int width = glw->width();
          int height = glw->height();

          Coord bbMin(width-x, height - y+h);
          Coord bbMax(width-(x+w), height - y);

          if (abs(bbMax[0] - bbMin[0]) > 1 && abs(bbMax[1] - bbMin[1]) > 1) {

            BoundingBox sceneBB;
            sceneBB.expand(glw->getScene()->getGraphCamera().viewportTo3DWorld(glw->screenToViewport(bbMin)));
            sceneBB.expand(glw->getScene()->getGraphCamera().viewportTo3DWorld(glw->screenToViewport(bbMax)));

            QtGlSceneZoomAndPanAnimator zoomAnPan(glw, sceneBB);
            zoomAnPan.animateZoomAndPan();
          }
        }
      }

      return true;
    }
  }

  return false;
}
Ejemplo n.º 2
0
void BoundingSphere::merge(const BoundingBox& box)
{
    if (box.isEmpty())
        return;

    const Vector3& min = box.min;
    const Vector3& max = box.max;

    // Find the corner of the bounding box that is farthest away from this sphere's center.
    float v1x = min.x - center.x;
    float v1y = min.y - center.y;
    float v1z = min.z - center.z;
    float v2x = max.x - center.x;
    float v2y = max.y - center.y;
    float v2z = max.z - center.z;
    float fx = min.x;
    float fy = min.y;
    float fz = min.z;

    if (v2x > v1x)
    {
        fx = max.x;
    }
    if (v2y > v1y)
    {
        fy = max.y;
    }
    if (v2z > v1z)
    {
        fz = max.z;
    }

    // Calculate the unit vector and the distance between the center and the farthest point.
    v1x = center.x - fx;
    v1y = center.y - fy;
    v1z = center.z - fz;
    float distance = sqrt(v1x * v1x + v1y * v1y + v1z * v1z);

    // If the box is inside the sphere, we are done.
    if (distance <= radius)
    {
        return;
    }

    // Calculate the unit vector between the center and the farthest point.
    GP_ASSERT(distance != 0.0f);
    float dI = 1.0f / distance;
    v1x *= dI;
    v1y *= dI;
    v1z *= dI;

    // Calculate the new radius.
    float r = (radius + distance) * 0.5f;

    // Calculate the new center.
    v1x = v1x * r + fx;
    v1y = v1y * r + fy;
    v1z = v1z * r + fz;

    // Set the new center and radius.
    center.x = v1x;
    center.y = v1y;
    center.z = v1z;
    radius = r;
}
Ejemplo n.º 3
0
void WriteVertex(float*& dest, aiMesh* mesh, unsigned index, unsigned elementMask, BoundingBox& box,
    const Matrix3x4& vertexTransform, const Matrix3& normalTransform, Vector<PODVector<unsigned char> >& blendIndices,
    Vector<PODVector<float> >& blendWeights)
{
    Vector3 vertex = vertexTransform * ToVector3(mesh->mVertices[index]);
    box.Merge(vertex);
    *dest++ = vertex.x_;
    *dest++ = vertex.y_;
    *dest++ = vertex.z_;
    if (elementMask & MASK_NORMAL)
    {
        Vector3 normal = normalTransform * ToVector3(mesh->mNormals[index]);
        *dest++ = normal.x_;
        *dest++ = normal.y_;
        *dest++ = normal.z_;
    }
    if (elementMask & MASK_COLOR)
    {
        *((unsigned*)dest) = Color(mesh->mColors[0][index].r, mesh->mColors[0][index].g, mesh->mColors[0][index].b,
            mesh->mColors[0][index].a).ToUInt();
        ++dest;
    }
    if (elementMask & MASK_TEXCOORD1)
    {
        Vector3 texCoord = ToVector3(mesh->mTextureCoords[0][index]);
        *dest++ = texCoord.x_;
        *dest++ = texCoord.y_;
    }
    if (elementMask & MASK_TEXCOORD2)
    {
        Vector3 texCoord = ToVector3(mesh->mTextureCoords[1][index]);
        *dest++ = texCoord.x_;
        *dest++ = texCoord.y_;
    }
    if (elementMask & MASK_TANGENT)
    {
        Vector3 tangent = normalTransform * ToVector3(mesh->mTangents[index]);
        Vector3 normal = normalTransform * ToVector3(mesh->mNormals[index]);
        Vector3 bitangent = normalTransform * ToVector3(mesh->mBitangents[index]);
        // Check handedness
        float w = 1.0f;
        if ((tangent.CrossProduct(normal)).DotProduct(bitangent) < 0.5f)
            w = -1.0f;

        *dest++ = tangent.x_;
        *dest++ = tangent.y_;
        *dest++ = tangent.z_;
        *dest++ = w;
    }
    if (elementMask & MASK_BLENDWEIGHTS)
    {
        for (unsigned i = 0; i < 4; ++i)
        {
            if (i < blendWeights[index].Size())
                *dest++ = blendWeights[index][i];
            else
                *dest++ = 0.0f;
        }
    }
    if (elementMask & MASK_BLENDINDICES)
    {
        unsigned char* destBytes = (unsigned char*)dest;
        ++dest;
        for (unsigned i = 0; i < 4; ++i)
        {
            if (i < blendIndices[index].Size())
                *destBytes++ = blendIndices[index][i];
            else
                *destBytes++ = 0;
        }
    }
}
Ejemplo n.º 4
0
BoundingBox MinimumBoundingBox::getMinimumBoundingBox(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud)
{
    BoundingBox bb;
    std::vector< pcl::Vertices > polygons;
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_hull (new pcl::PointCloud<pcl::PointXYZRGB>);
    pcl::ConvexHull<pcl::PointXYZRGB> chull;
    chull.setInputCloud (cloud);
    chull.setDimension(3);
    chull.reconstruct (*cloud_hull,polygons);

    yarp::sig::Vector x1;
    yarp::sig::Vector x2;
    yarp::sig::Vector x3;
    yarp::sig::Vector y1;
    yarp::sig::Vector y2;
    yarp::sig::Vector y3;
    yarp::sig::Vector z1;
    yarp::sig::Vector z2;
    yarp::sig::Vector z3;

    for (int i=0; i<polygons.size(); i++)
    {
        pcl::Vertices vertex=polygons.at(i);
        x1.push_back(cloud_hull->at(vertex.vertices[0]).x);
        x2.push_back(cloud_hull->at(vertex.vertices[1]).x);
        x3.push_back(cloud_hull->at(vertex.vertices[2]).x);
        y1.push_back(cloud_hull->at(vertex.vertices[0]).y);
        y2.push_back(cloud_hull->at(vertex.vertices[1]).y);
        y3.push_back(cloud_hull->at(vertex.vertices[2]).y);
        z1.push_back(cloud_hull->at(vertex.vertices[0]).z);
        z2.push_back(cloud_hull->at(vertex.vertices[1]).z);
        z3.push_back(cloud_hull->at(vertex.vertices[2]).z);
    }

    Matrix pointCloud(cloud_hull->size(),3);
    for (int i=0; i<cloud_hull->size(); i++)
    {
        pointCloud(i,0)=cloud_hull->at(i).x;
        pointCloud(i,1)=cloud_hull->at(i).y;
        pointCloud(i,2)=cloud_hull->at(i).z;
    }

    yarp::sig::Vector v1x=x2-x1;
    yarp::sig::Vector v1y=y2-y1;
    yarp::sig::Vector v1z=z2-z1;
    std::vector<yarp::sig::Vector> edges1;

    retrieveEdges(v1x,v1y,v1z,edges1);

    yarp::sig::Vector v2x=x3-x1;
    yarp::sig::Vector v2y=y3-y1;
    yarp::sig::Vector v2z=z3-z1;
    std::vector<yarp::sig::Vector> edges2;

    retrieveEdges2(v2x,v2y,v2z,edges1,edges2);

    std::vector<yarp::sig::Vector> crossProduct;
    for (int i=0; i<edges1.size(); i++)
    {
        yarp::sig::Vector vect=cross(edges1.at(i),edges2.at(i));
        crossProduct.push_back(vect);
    }

    yarp::sig::Vector alpha;
    yarp::sig::Vector beta;
    yarp::sig::Vector gamma;
    eulerAngles(edges1, edges2, crossProduct, alpha, beta, gamma);

    Matrix minmax(2,3);
    double minVol=100000;
    Matrix rot2;

    for (int i=0; i<alpha.size(); i++)
    {
        Matrix rot;
        buildRotMat3(alpha[i],beta[i],gamma[i],rot);
        Matrix xyz_i=pointCloud*rot;
        findRotation(xyz_i,rot2);

        Matrix rot3dim=eye(3,3);
        rot3dim.setSubmatrix(rot2,0,0);
        Matrix rotation=rot*rot3dim;

        xyz_i=pointCloud*rotation;
        yarp::sig::Vector minimum;
        Helpers::min(xyz_i,minimum);
        yarp::sig::Vector maximum;
        Helpers::max(xyz_i,maximum);
        yarp::sig::Vector h=maximum-minimum;

        double prod=h[0]*h[1]*h[2];
        if (prod<minVol)
        {
            minVol=prod;
            bb.setOrientation(rotation);
            minmax.setRow(0,minimum);
            minmax.setRow(1,maximum);
        }
    }
    Matrix cornerpointsTmp(8,3);
    assignCorners(minmax,cornerpointsTmp);
    Matrix cornerpoints=cornerpointsTmp*(bb.getOrientation().transposed());

    std::vector<iCub::data3D::PointXYZ> corners;
    for (unsigned int i=0; i<cornerpoints.rows(); i++)
        corners.push_back(PointXYZ(cornerpoints(i,0),cornerpoints(i,1),cornerpoints(i,2)));

    bb.setCorners(corners);
    return bb;
}
Ejemplo n.º 5
0
    bool Collider::Check(const BoundingBox &BB,  const Sphere &SP)
    {

        real dmin = 0.0;

        if(SP.position.x < BB.Mininmum(X))
        {
            dmin += ((SP.position.x - BB.Mininmum(X))*(SP.position.x - BB.Mininmum(X))) ;
        }
        else if (SP.position.x > BB.Mininmum(X))
        {
            dmin += ((SP.position.x - BB.Mininmum(X))*(SP.position.x - BB.Maximum(X))) ;
        }

        if(SP.position.x < BB.Mininmum(X))
        {
            dmin += ((SP.position.x - BB.Mininmum(X))*(SP.position.x - BB.Mininmum(X))) ;
        }
        else if (SP.position.x > BB.Mininmum(X))
        {
            dmin += ((SP.position.x - BB.Mininmum(X))*(SP.position.x - BB.Maximum(X))) ;
        }

        if(SP.position.y < BB.Mininmum(Y))
        {
            dmin += ((SP.position.y - BB.Mininmum(Y))*(SP.position.y - BB.Mininmum(Y))) ;
        }
        else if (SP.position.y > BB.Mininmum(Y))
        {
            dmin += ((SP.position.y - BB.Mininmum(Y))*(SP.position.y - BB.Maximum(Y))) ;
        }

        if(SP.position.z < BB.Mininmum(Z))
        {
            dmin += ((SP.position.z - BB.Mininmum(Z))*(SP.position.z - BB.Mininmum(Z))) ;
        }
        else if (SP.position.z > BB.Mininmum(Z))
        {
            dmin += ((SP.position.z - BB.Mininmum(Z))*(SP.position.z - BB.Maximum(Z))) ;
        }


          return dmin <= (SP.radious*SP.radious);

    }
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool ShaderUniforms::onInitialize()
{
    m_propGlobalUniformSet = new PropertyBool("Use global uniform set", true);
    m_propertyPublisher->publishProperty(m_propGlobalUniformSet.p());

    // Create the single shader program with default uniforms
    ref<ShaderProgram> shaderProg;
    {
        ShaderProgramGenerator shaderGen("ShaderUniforms", ShaderSourceProvider::instance());
        shaderGen.addVertexCodeFromFile("ShaderUniforms_Vert");
        shaderGen.addFragmentCode(ShaderSourceRepository::light_SimpleHeadlight);
        shaderGen.addFragmentCodeFromFile("ShaderUniforms_Frag");
        shaderProg = shaderGen.generate();
        shaderProg->setDefaultUniform(new UniformFloat("u_color0", Color3f(Color3::WHITE)));
        shaderProg->setDefaultUniform(new UniformFloat("u_color1", Color3f(Color3::MAGENTA)));
        shaderProg->setDefaultUniform(new UniformFloat("u_colorMixFactor", 1.0f));
    }

    // No uniforms, relies only on the shader program defaults
    m_effNoUniforms = new Effect;
    m_effNoUniforms->setShaderProgram(shaderProg.p());

    // Effect with only mix factor set (uses colors from default)
    m_effWithSomeUniforms = new Effect;
    m_effWithSomeUniforms->setShaderProgram(shaderProg.p());
    m_effWithSomeUniforms->setUniform(new UniformFloat("u_colorMixFactor", 0));

    // Fully specified uniforms
    m_effWithAllUniforms = new Effect;
    m_effWithAllUniforms->setShaderProgram(shaderProg.p());
    m_effWithAllUniforms->setUniform(new UniformFloat("u_color0", Color3f(Color3::BLACK)));
    m_effWithAllUniforms->setUniform(new UniformFloat("u_color1", Color3f(Color3::GREEN)));
    m_effWithAllUniforms->setUniform(new UniformFloat("u_colorMixFactor", 1.0f));


    // Box part
    ref<Part> boxPart = new Part;
    {
        BoxGenerator gen;
        gen.setCenterAndExtent(Vec3d(-2, 0, 0), Vec3d(2, 2, 2));
        GeometryBuilderDrawableGeo builder;
        gen.generate(&builder);
        boxPart->setDrawable(builder.drawableGeo().p());
    }

    // Sphere part
    ref<Part> spherePart = new Part;
    {
        GeometryBuilderDrawableGeo builder;
        GeometryUtils::createSphere(1, 10, 10, &builder);
        spherePart->setDrawable(builder.drawableGeo().p());
    }

    // Cylinder part
    ref<Part> cylinderPart = new Part;
    {
        GeometryBuilderDrawableGeo builder;
        GeometryUtils::createObliqueCylinder(1, 1, 2, 0, 0, 10, true, true, true, 1, &builder);
        ref<DrawableGeo> geo = builder.drawableGeo();
        geo->transform(Mat4d::fromTranslation(Vec3d(2, 0, -1)));
        cylinderPart->setDrawable(geo.p());
    }

    ref<ModelBasicList> myModel = new ModelBasicList;
    boxPart->setEffect(m_effNoUniforms.p());
    spherePart->setEffect(m_effWithSomeUniforms.p());
    cylinderPart->setEffect(m_effWithAllUniforms.p());

    myModel->addPart(boxPart.p());
    myModel->addPart(spherePart.p());
    myModel->addPart(cylinderPart.p());
    myModel->updateBoundingBoxesRecursive();


    m_renderSequence->firstRendering()->scene()->addModel(myModel.p());

    BoundingBox bb = myModel->boundingBox();
    if (bb.isValid())
    {
        m_camera->fitView(bb, Vec3d::Y_AXIS, Vec3d::Z_AXIS);
    }

    applyCurrentProperties();

    return true;
}
Ejemplo n.º 7
0
/***************************************************************
* Function: setSurfaceScalingHint()
***************************************************************/
void CAVEGroupIconSurface::setSurfaceScalingHint(const BoundingBox& boundingbox)
{
    gScaleVal = (CAVEGeodeIcon::gSphereBoundRadius) / (boundingbox.radius());
}
Ejemplo n.º 8
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool PointSprites::onInitialize()
{
    ref<ModelBasicList> model = new ModelBasicList;

    bool useShaders = true;

    {
        GeometryBuilderDrawableGeo builder;
        GeometryUtils::createSphere(1, 10, 10, &builder);
        ref<DrawableGeo> geo = builder.drawableGeo();

        ref<Effect> eff = new Effect;

        if (useShaders)
        {
            cvf::ShaderProgramGenerator gen("SimpleHeadlight", cvf::ShaderSourceProvider::instance());
            gen.configureStandardHeadlightColor();
            ref<ShaderProgram> prog = gen.generate();
            eff->setShaderProgram(prog.p());
            eff->setUniform(new UniformFloat("u_color", Color4f(Color3::YELLOW)));
        }
        else
        {
            eff->setRenderState(new RenderStateMaterial_FF(RenderStateMaterial_FF::PURE_YELLOW));
        }

        ref<Part> part = new Part;
        part->setDrawable(geo.p());
        part->setEffect(eff.p());

        model->addPart(part.p());
    }

    {
        ref<Vec3fArray> vertices = new Vec3fArray;
        vertices->reserve(10);
        vertices->add(Vec3f(0, 0, 0));
        vertices->add(Vec3f(-3, 0, 0));
        vertices->add(Vec3f(3, 0, 0));

        ref<UIntArray> indices = new UIntArray(vertices->size());
        indices->setConsecutive(0);

        ref<PrimitiveSetIndexedUInt> primSet = new PrimitiveSetIndexedUInt(PT_POINTS);
        primSet->setIndices(indices.p());

        ref<DrawableGeo> geo = new DrawableGeo;
        geo->setVertexArray(vertices.p());
        geo->addPrimitiveSet(primSet.p());

        ref<Effect> eff = new Effect;

        if (useShaders)
        {
            bool useTextureSprite = true;

            cvf::ShaderProgramGenerator gen("PointSprites", cvf::ShaderSourceProvider::instance());
            gen.addVertexCode(ShaderSourceRepository::vs_DistanceScaledPoints);
            
            if (useTextureSprite)  gen.addFragmentCode(ShaderSourceRepository::src_TextureFromPointCoord);
            else                   gen.addFragmentCode(ShaderSourceRepository::src_Color);
            gen.addFragmentCode(ShaderSourceRepository::fs_CenterLitSpherePoints);

            ref<cvf::ShaderProgram> prog = gen.generate();
            eff->setShaderProgram(prog.p());
            eff->setUniform(new UniformFloat("u_pointRadius", 1.0f));

            if (useTextureSprite)
            {
                ref<Texture> tex = createTexture();
                ref<Sampler> sampler = new Sampler;
                sampler->setMinFilter(Sampler::LINEAR);
                sampler->setMagFilter(Sampler::NEAREST);
                sampler->setWrapModeS(Sampler::REPEAT);
                sampler->setWrapModeT(Sampler::REPEAT);
                ref<RenderStateTextureBindings> texBind = new RenderStateTextureBindings(tex.p(), sampler.p(), "u_texture2D");
                eff->setRenderState(texBind.p());
            }
            else
            {
                eff->setUniform(new UniformFloat("u_color", Color4f(Color3::RED)));
            }

            ref<RenderStatePoint> point = new RenderStatePoint(RenderStatePoint::PROGRAM_SIZE);
            point->enablePointSprite(true);
            eff->setRenderState(point.p());
        }
        else
        {
            eff->setRenderState(new RenderStateLighting_FF(false));
            eff->setRenderState(new RenderStateMaterial_FF(RenderStateMaterial_FF::PURE_MAGENTA));

            ref<RenderStatePoint> point = new RenderStatePoint(RenderStatePoint::FIXED_SIZE);
            point->enablePointSprite(true);
            point->setSize(600.0f);
            eff->setRenderState(point.p());
        }

        ref<Part> part = new Part;
        part->setDrawable(geo.p());
        part->setEffect(eff.p());

        model->addPart(part.p());
    }

    model->updateBoundingBoxesRecursive();
    m_renderSequence->firstRendering()->scene()->addModel(model.p());

    BoundingBox bb = model->boundingBox();
    if (bb.isValid())
    {
        m_camera->fitView(bb, -Vec3d::Z_AXIS, Vec3d::Y_AXIS);
        if (m_usePerspective)
        {
            m_camera->setProjectionAsPerspective(m_fovScale*40.0, m_nearPlane, m_camera->farPlane());
        }
        else
        {
            m_camera->setProjectionAsOrtho(m_fovScale*bb.extent().length(), m_nearPlane, m_camera->farPlane());
        }
    }

    return true;
}
Ejemplo n.º 9
0
void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubMeshes, bool exportMorphs)
{
    File meshFileSource(context_);
    meshFileSource.Open(inputFileName);
    if (!meshFile_->Load(meshFileSource))
        ErrorExit("Could not load input file " + inputFileName);
    
    XMLElement root = meshFile_->GetRoot("mesh");
    XMLElement subMeshes = root.GetChild("submeshes");
    XMLElement skeletonLink = root.GetChild("skeletonlink");
    if (root.IsNull())
        ErrorExit("Could not load input file " + inputFileName);
    
    String skeletonName = skeletonLink.GetAttribute("name");
    if (!skeletonName.Empty())
        LoadSkeleton(GetPath(inputFileName) + GetFileName(skeletonName) + ".skeleton.xml");
    
    // Check whether there's benefit of avoiding 32bit indices by splitting each submesh into own buffer
    XMLElement subMesh = subMeshes.GetChild("submesh");
    unsigned totalVertices = 0;
    unsigned maxSubMeshVertices = 0;
    while (subMesh)
    {
        materialNames_.Push(subMesh.GetAttribute("material"));
        XMLElement geometry = subMesh.GetChild("geometry");
        if (geometry)
        {
            unsigned vertices = geometry.GetInt("vertexcount");
            totalVertices += vertices;
            if (maxSubMeshVertices < vertices)
                maxSubMeshVertices = vertices;
        }
        ++numSubMeshes_;
        
        subMesh = subMesh.GetNext("submesh");
    }
    
    XMLElement sharedGeometry = root.GetChild("sharedgeometry");
    if (sharedGeometry)
    {
        unsigned vertices = sharedGeometry.GetInt("vertexcount");
        totalVertices += vertices;
        if (maxSubMeshVertices < vertices)
            maxSubMeshVertices = vertices;
    }
    
    if (!sharedGeometry && (splitSubMeshes || (totalVertices > 65535 && maxSubMeshVertices <= 65535)))
    {
        useOneBuffer_ = false;
        vertexBuffers_.Resize(numSubMeshes_);
        indexBuffers_.Resize(numSubMeshes_);
    }
    else
    {
        vertexBuffers_.Resize(1);
        indexBuffers_.Resize(1);
    }
    
    subMesh = subMeshes.GetChild("submesh");
    unsigned indexStart = 0;
    unsigned vertexStart = 0;
    unsigned subMeshIndex = 0;
    
    PODVector<unsigned> vertexStarts;
    vertexStarts.Resize(numSubMeshes_);
    
    while (subMesh)
    {
        XMLElement geometry = subMesh.GetChild("geometry");
        XMLElement faces = subMesh.GetChild("faces");
        
        // If no submesh vertexbuffer, process the shared geometry, but do it only once
        unsigned vertices = 0;
        if (!geometry)
        {
            vertexStart = 0;
            if (!subMeshIndex)
                geometry = root.GetChild("sharedgeometry");
        }
        
        if (geometry)
            vertices = geometry.GetInt("vertexcount");
        
        ModelSubGeometryLodLevel subGeometryLodLevel;
        ModelVertexBuffer* vBuf;
        ModelIndexBuffer* iBuf;
        
        if (useOneBuffer_)
        {
            vBuf = &vertexBuffers_[0];
            if (vertices)
                vBuf->vertices_.Resize(vertexStart + vertices);
            iBuf = &indexBuffers_[0];
            
            subGeometryLodLevel.vertexBuffer_ = 0;
            subGeometryLodLevel.indexBuffer_ = 0;
        }
        else
        {
            vertexStart = 0;
            indexStart = 0;
            
            vBuf = &vertexBuffers_[subMeshIndex];
            vBuf->vertices_.Resize(vertices);
            iBuf = &indexBuffers_[subMeshIndex];
            
            subGeometryLodLevel.vertexBuffer_ = subMeshIndex;
            subGeometryLodLevel.indexBuffer_ = subMeshIndex;
        }
        
        // Store the start vertex for later use
        vertexStarts[subMeshIndex] = vertexStart;
        
        // Ogre may have multiple buffers in one submesh. These will be merged into one
        XMLElement bufferDef;
        if (geometry)
            bufferDef = geometry.GetChild("vertexbuffer");
        
        while (bufferDef)
        {
            if (bufferDef.HasAttribute("positions"))
                vBuf->elementMask_ |= MASK_POSITION;
            if (bufferDef.HasAttribute("normals"))
                vBuf->elementMask_ |= MASK_NORMAL;
            if (bufferDef.HasAttribute("texture_coords"))
            {
                vBuf->elementMask_ |= MASK_TEXCOORD1;
                if (bufferDef.GetInt("texture_coords") > 1)
                    vBuf->elementMask_ |= MASK_TEXCOORD2;
            }
            
            unsigned vertexNum = vertexStart;
            if (vertices)
            {
                XMLElement vertex = bufferDef.GetChild("vertex");
                while (vertex)
                {
                    XMLElement position = vertex.GetChild("position");
                    if (position)
                    {
                        // Convert from right- to left-handed
                        float x = position.GetFloat("x");
                        float y = position.GetFloat("y");
                        float z = position.GetFloat("z");
                        Vector3 vec(x, y, -z);
                        
                        vBuf->vertices_[vertexNum].position_ = vec;
                        boundingBox_.Merge(vec);
                    }
                    XMLElement normal = vertex.GetChild("normal");
                    if (normal)
                    {
                        // Convert from right- to left-handed
                        float x = normal.GetFloat("x");
                        float y = normal.GetFloat("y");
                        float z = normal.GetFloat("z");
                        Vector3 vec(x, y, -z);
                        
                        vBuf->vertices_[vertexNum].normal_ = vec;
                    }
                    XMLElement uv = vertex.GetChild("texcoord");
                    if (uv)
                    {
                        float x = uv.GetFloat("u");
                        float y = uv.GetFloat("v");
                        Vector2 vec(x, y);
                        
                        vBuf->vertices_[vertexNum].texCoord1_ = vec;
                        
                        if (vBuf->elementMask_ & MASK_TEXCOORD2)
                        {
                            uv = uv.GetNext("texcoord");
                            if (uv)
                            {
                                float x = uv.GetFloat("u");
                                float y = uv.GetFloat("v");
                                Vector2 vec(x, y);
                                
                                vBuf->vertices_[vertexNum].texCoord2_ = vec;
                            }
                        }
                    }
                    
                    vertexNum++;
                    vertex = vertex.GetNext("vertex");
                }
            }
            
            bufferDef = bufferDef.GetNext("vertexbuffer");
        }
        
        unsigned triangles = faces.GetInt("count");
        unsigned indices = triangles * 3;
        
        XMLElement triangle = faces.GetChild("face");
        while (triangle)
        {
            unsigned v1 = triangle.GetInt("v1");
            unsigned v2 = triangle.GetInt("v2");
            unsigned v3 = triangle.GetInt("v3");
            iBuf->indices_.Push(v3 + vertexStart);
            iBuf->indices_.Push(v2 + vertexStart);
            iBuf->indices_.Push(v1 + vertexStart);
            triangle = triangle.GetNext("face");
        }
        
        subGeometryLodLevel.indexStart_ = indexStart;
        subGeometryLodLevel.indexCount_ = indices;
        if (vertexStart + vertices > 65535)
            iBuf->indexSize_ = sizeof(unsigned);
        
        XMLElement boneAssignments = subMesh.GetChild("boneassignments");
        if (bones_.Size())
        {
            if (boneAssignments)
            {
                XMLElement boneAssignment = boneAssignments.GetChild("vertexboneassignment");
                while (boneAssignment)
                {
                    unsigned vertex = boneAssignment.GetInt("vertexindex") + vertexStart;
                    unsigned bone = boneAssignment.GetInt("boneindex");
                    float weight = boneAssignment.GetFloat("weight");
                    
                    BoneWeightAssignment assign;
                    assign.boneIndex_ = bone;
                    assign.weight_ = weight;
                    // Source data might have 0 weights. Disregard these
                    if (assign.weight_ > 0.0f)
                    {
                        subGeometryLodLevel.boneWeights_[vertex].Push(assign);
                        
                        // Require skinning weight to be sufficiently large before vertex contributes to bone hitbox
                        if (assign.weight_ > 0.33f)
                        {
                            // Check distance of vertex from bone to get bone max. radius information
                            Vector3 bonePos = bones_[bone].derivedPosition_;
                            Vector3 vertexPos = vBuf->vertices_[vertex].position_;
                            float distance = (bonePos - vertexPos).Length();
                            if (distance > bones_[bone].radius_)
                            {
                                bones_[bone].collisionMask_ |= 1;
                                bones_[bone].radius_ = distance;
                            }
                            // Build the hitbox for the bone
                            bones_[bone].boundingBox_.Merge(bones_[bone].inverseWorldTransform_ * (vertexPos));
                            bones_[bone].collisionMask_ |= 2;
                        }
                    }
                    boneAssignment = boneAssignment.GetNext("vertexboneassignment");
                }
            }
            
            if ((subGeometryLodLevel.boneWeights_.Size()) && bones_.Size())
            {
                vBuf->elementMask_ |= MASK_BLENDWEIGHTS | MASK_BLENDINDICES;
                bool sorted = false;
                
                // If amount of bones is larger than supported by HW skinning, must remap per submesh
                if (bones_.Size() > MAX_SKIN_MATRICES)
                {
                    HashMap<unsigned, unsigned> usedBoneMap;
                    unsigned remapIndex = 0;
                    for (HashMap<unsigned, PODVector<BoneWeightAssignment> >::Iterator i =
                        subGeometryLodLevel.boneWeights_.Begin(); i != subGeometryLodLevel.boneWeights_.End(); ++i)
                    {
                        // Sort the bone assigns by weight
                        Sort(i->second_.Begin(), i->second_.End(), CompareWeights);
                        
                        // Use only the first 4 weights
                        for (unsigned j = 0; j < i->second_.Size() && j < 4; ++j)
                        {
                            unsigned originalIndex = i->second_[j].boneIndex_;
                            if (!usedBoneMap.Contains(originalIndex))
                            {
                                usedBoneMap[originalIndex] = remapIndex;
                                remapIndex++;
                            }
                            i->second_[j].boneIndex_ = usedBoneMap[originalIndex];
                        }
                    }
                    
                    // If still too many bones in one subgeometry, error
                    if (usedBoneMap.Size() > MAX_SKIN_MATRICES)
                        ErrorExit("Too many bones in submesh " + String(subMeshIndex + 1));
                    
                    // Write mapping of vertex buffer bone indices to original bone indices
                    subGeometryLodLevel.boneMapping_.Resize(usedBoneMap.Size());
                    for (HashMap<unsigned, unsigned>::Iterator j = usedBoneMap.Begin(); j != usedBoneMap.End(); ++j)
                        subGeometryLodLevel.boneMapping_[j->second_] = j->first_;
                    
                    sorted = true;
                }
                
                for (HashMap<unsigned, PODVector<BoneWeightAssignment> >::Iterator i = subGeometryLodLevel.boneWeights_.Begin();
                    i != subGeometryLodLevel.boneWeights_.End(); ++i)
                {
                    // Sort the bone assigns by weight, if not sorted yet in bone remapping pass
                    if (!sorted)
                        Sort(i->second_.Begin(), i->second_.End(), CompareWeights);
                    
                    float totalWeight = 0.0f;
                    float normalizationFactor = 0.0f;
                    
                    // Calculate normalization factor in case there are more than 4 blend weights, or they do not add up to 1
                    for (unsigned j = 0; j < i->second_.Size() && j < 4; ++j)
                        totalWeight += i->second_[j].weight_;
                    if (totalWeight > 0.0f)
                        normalizationFactor = 1.0f / totalWeight;
                    
                    for (unsigned j = 0; j < i->second_.Size() && j < 4; ++j)
                    {
                        vBuf->vertices_[i->first_].blendIndices_[j] = i->second_[j].boneIndex_;
                        vBuf->vertices_[i->first_].blendWeights_[j] = i->second_[j].weight_ * normalizationFactor;
                    }
                    
                    // If there are less than 4 blend weights, fill rest with zero
                    for (unsigned j = i->second_.Size(); j < 4; ++j)
                    {
                        vBuf->vertices_[i->first_].blendIndices_[j] = 0;
                        vBuf->vertices_[i->first_].blendWeights_[j] = 0.0f;
                    }
                    
                    vBuf->vertices_[i->first_].hasBlendWeights_ = true;
                }
            }
        }
        else if (boneAssignments)
            PrintLine("No skeleton loaded, skipping skinning information");
        
        // Calculate center for the subgeometry
        Vector3 center = Vector3::ZERO;
        for (unsigned i = 0; i < iBuf->indices_.Size(); i += 3)
        {
            center += vBuf->vertices_[iBuf->indices_[i]].position_;
            center += vBuf->vertices_[iBuf->indices_[i + 1]].position_;
            center += vBuf->vertices_[iBuf->indices_[i + 2]].position_;
        }
        if (iBuf->indices_.Size())
            center /= (float)iBuf->indices_.Size();
        subGeometryCenters_.Push(center);
        
        indexStart += indices;
        vertexStart += vertices;
        
        OptimizeIndices(&subGeometryLodLevel, vBuf, iBuf);
        
        PrintLine("Processed submesh " + String(subMeshIndex + 1) + ": " + String(vertices) + " vertices " + 
            String(triangles) + " triangles");
        Vector<ModelSubGeometryLodLevel> thisSubGeometry;
        thisSubGeometry.Push(subGeometryLodLevel);
        subGeometries_.Push(thisSubGeometry);
        
        subMesh = subMesh.GetNext("submesh");
        subMeshIndex++;
    }
    
    // Process LOD levels, if any
    XMLElement lods = root.GetChild("levelofdetail");
    if (lods)
    {
        try
        {
            // For now, support only generated LODs, where the vertices are the same
            XMLElement lod = lods.GetChild("lodgenerated");
            while (lod)
            {
                float distance = M_EPSILON;
                if (lod.HasAttribute("fromdepthsquared"))
                    distance = sqrtf(lod.GetFloat("fromdepthsquared"));
                if (lod.HasAttribute("value"))
                    distance = lod.GetFloat("value");
                XMLElement lodSubMesh = lod.GetChild("lodfacelist");
                while (lodSubMesh)
                {
                    unsigned subMeshIndex = lodSubMesh.GetInt("submeshindex");
                    unsigned triangles = lodSubMesh.GetInt("numfaces");
                    
                    ModelSubGeometryLodLevel newLodLevel;
                    ModelSubGeometryLodLevel& originalLodLevel = subGeometries_[subMeshIndex][0];
                    
                    // Copy all initial values
                    newLodLevel = originalLodLevel;
                    
                    ModelVertexBuffer* vBuf;
                    ModelIndexBuffer* iBuf;
                    
                    if (useOneBuffer_)
                    {
                        vBuf = &vertexBuffers_[0];
                        iBuf = &indexBuffers_[0];
                    }
                    else
                    {
                        vBuf = &vertexBuffers_[subMeshIndex];
                        iBuf = &indexBuffers_[subMeshIndex];
                    }
                    
                    unsigned indexStart = iBuf->indices_.Size();
                    unsigned indexCount = triangles * 3;
                    unsigned vertexStart = vertexStarts[subMeshIndex];
                    
                    newLodLevel.distance_ = distance;
                    newLodLevel.indexStart_ = indexStart;
                    newLodLevel.indexCount_ = indexCount;
                    
                    // Append indices to the original index buffer
                    XMLElement triangle = lodSubMesh.GetChild("face");
                    while (triangle)
                    {
                        unsigned v1 = triangle.GetInt("v1");
                        unsigned v2 = triangle.GetInt("v2");
                        unsigned v3 = triangle.GetInt("v3");
                        iBuf->indices_.Push(v3 + vertexStart);
                        iBuf->indices_.Push(v2 + vertexStart);
                        iBuf->indices_.Push(v1 + vertexStart);
                        triangle = triangle.GetNext("face");
                    }
                    
                    OptimizeIndices(&newLodLevel, vBuf, iBuf);
                    
                    subGeometries_[subMeshIndex].Push(newLodLevel);
                    PrintLine("Processed LOD level for submesh " + String(subMeshIndex + 1) + ": distance " + String(distance));
                    
                    lodSubMesh = lodSubMesh.GetNext("lodfacelist");
                }
                lod = lod.GetNext("lodgenerated");
            }
        }
        catch (...) {}
    }
    
    // Process poses/morphs
    // First find out all pose definitions
    if (exportMorphs)
    {
        try
        {
            Vector<XMLElement> poses;
            XMLElement posesRoot = root.GetChild("poses");
            if (posesRoot)
            {
                XMLElement pose = posesRoot.GetChild("pose");
                while (pose)
                {
                    poses.Push(pose);
                    pose = pose.GetNext("pose");
                }
            }
            
            // Then process animations using the poses
            XMLElement animsRoot = root.GetChild("animations");
            if (animsRoot)
            {
                XMLElement anim = animsRoot.GetChild("animation");
                while (anim)
                {
                    String name = anim.GetAttribute("name");
                    float length = anim.GetFloat("length");
                    HashSet<unsigned> usedPoses;
                    XMLElement tracks = anim.GetChild("tracks");
                    if (tracks)
                    {
                        XMLElement track = tracks.GetChild("track");
                        while (track)
                        {
                            XMLElement keyframes = track.GetChild("keyframes");
                            if (keyframes)
                            {
                                XMLElement keyframe = keyframes.GetChild("keyframe");
                                while (keyframe)
                                {
                                    float time = keyframe.GetFloat("time");
                                    XMLElement poseref = keyframe.GetChild("poseref");
                                    // Get only the end pose
                                    if (poseref && time == length)
                                        usedPoses.Insert(poseref.GetInt("poseindex"));
                                    
                                    keyframe = keyframe.GetNext("keyframe");
                                }
                            }
                            track = track.GetNext("track");
                        }
                    }
                    
                    if (usedPoses.Size())
                    {
                        ModelMorph newMorph;
                        newMorph.name_ = name;
                        
                        if (useOneBuffer_)
                            newMorph.buffers_.Resize(1);
                        else
                            newMorph.buffers_.Resize(usedPoses.Size());
                        
                        unsigned bufIndex = 0;
                        
                        for (HashSet<unsigned>::Iterator i = usedPoses.Begin(); i != usedPoses.End(); ++i)
                        {
                            XMLElement pose = poses[*i];
                            unsigned targetSubMesh = pose.GetInt("index");
                            XMLElement poseOffset = pose.GetChild("poseoffset");
                        
                            if (useOneBuffer_)
                                newMorph.buffers_[bufIndex].vertexBuffer_ = 0;
                            else
                                newMorph.buffers_[bufIndex].vertexBuffer_ = targetSubMesh;
                            
                            newMorph.buffers_[bufIndex].elementMask_ = MASK_POSITION;
                            
                            ModelVertexBuffer* vBuf = &vertexBuffers_[newMorph.buffers_[bufIndex].vertexBuffer_];
                            
                            while (poseOffset)
                            {
                                // Convert from right- to left-handed
                                unsigned vertexIndex = poseOffset.GetInt("index") + vertexStarts[targetSubMesh];
                                float x = poseOffset.GetFloat("x");
                                float y = poseOffset.GetFloat("y");
                                float z = poseOffset.GetFloat("z");
                                Vector3 vec(x, y, -z);
                                
                                if (vBuf->morphCount_ == 0)
                                {
                                    vBuf->morphStart_ = vertexIndex;
                                    vBuf->morphCount_ = 1;
                                }
                                else
                                {
                                    unsigned first = vBuf->morphStart_;
                                    unsigned last = first + vBuf->morphCount_ - 1;
                                    if (vertexIndex < first)
                                        first = vertexIndex;
                                    if (vertexIndex > last)
                                        last = vertexIndex;
                                    vBuf->morphStart_ = first;
                                    vBuf->morphCount_ = last - first + 1;
                                }
                                
                                ModelVertex newVertex;
                                newVertex.position_ = vec;
                                newMorph.buffers_[bufIndex].vertices_.Push(MakePair(vertexIndex, newVertex));
                                poseOffset = poseOffset.GetNext("poseoffset");
                            }
                            
                            if (!useOneBuffer_)
                                ++bufIndex;
                        }
                        morphs_.Push(newMorph);
                        PrintLine("Processed morph " + name + " with " + String(usedPoses.Size()) + " sub-poses");
                    }
                    
                    anim = anim.GetNext("animation");
                }
            }
        }
        catch (...) {}
    }
    
    // Check any of the buffers for vertices with missing blend weight assignments
    for (unsigned i = 0; i < vertexBuffers_.Size(); ++i)
    {
        if (vertexBuffers_[i].elementMask_ & MASK_BLENDWEIGHTS)
        {
            for (unsigned j = 0; j < vertexBuffers_[i].vertices_.Size(); ++j)
                if (!vertexBuffers_[i].vertices_[j].hasBlendWeights_)
                    ErrorExit("Found a vertex with missing skinning information");
        }
    }
    
    // Tangent generation
    if (generateTangents)
    {
        for (unsigned i = 0; i < subGeometries_.Size(); ++i)
        {
            for (unsigned j = 0; j < subGeometries_[i].Size(); ++j)
            {
                ModelVertexBuffer& vBuf = vertexBuffers_[subGeometries_[i][j].vertexBuffer_];
                ModelIndexBuffer& iBuf = indexBuffers_[subGeometries_[i][j].indexBuffer_];
                unsigned indexStart = subGeometries_[i][j].indexStart_;
                unsigned indexCount = subGeometries_[i][j].indexCount_;
                
                // If already has tangents, do not regenerate
                if (vBuf.elementMask_ & MASK_TANGENT || vBuf.vertices_.Empty() || iBuf.indices_.Empty())
                    continue;
                
                vBuf.elementMask_ |= MASK_TANGENT;
                
                if ((vBuf.elementMask_ & (MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1)) != (MASK_POSITION | MASK_NORMAL |
                    MASK_TEXCOORD1))
                    ErrorExit("To generate tangents, positions normals and texcoords are required");
                
                GenerateTangents(&vBuf.vertices_[0], sizeof(ModelVertex), &iBuf.indices_[0], sizeof(unsigned), indexStart,
                    indexCount, offsetof(ModelVertex, normal_), offsetof(ModelVertex, texCoord1_), offsetof(ModelVertex,
                    tangent_));
                
                PrintLine("Generated tangents");
            }
        }
    }
}
Ejemplo n.º 10
0
const bool BoundingBox::intersects(const BoundingBox &box) const
{
    return(this->minCorner() < box.maxCorner() &&
           this->maxCorner() > box.minCorner());
}
Ejemplo n.º 11
0
/*
====================
build
====================
*/
VOID Game::build()
{
    GUARD(Game::build);

    // build the color texture
    Image* image = GNEW(Image);
    CHECK(image);
    image->Width(256);
    image->Height(256);
    image->Depth(1);
    image->PixelFormat(PF_RGBA);
    image->DataType(DT_UNSIGNED_BYTE);
    mColorTexPtr = GNEW(Texture);
    CHECK(mColorTexPtr);
    mColorTexPtr->Load(image);

    // build the color rt
    mColorRTPtr = GNEW(Target(mColorTexPtr.Ptr()));
    CHECK(mColorRTPtr);

    // build the primitive
    mQuadPtr = GNEW(Primitive);
    CHECK(mQuadPtr);
    mQuadPtr->SetType(Primitive::PT_TRIANGLES);

    // set the wvp
    Constant* wvp_constant_ptr = GNEW(Constant);
    CHECK(wvp_constant_ptr);
    wvp_constant_ptr->SetMatrix(Matrix());
    mQuadPtr->SetConstant("gWVP",wvp_constant_ptr);

    // set the color texture
    Constant* texture_constant_ptr = GNEW(Constant);
    CHECK(texture_constant_ptr);
    texture_constant_ptr->SetTexture(mColorTexPtr.Ptr());
    mQuadPtr->SetConstant("gBaseTex",texture_constant_ptr);

    // set the shader
    Str shader_key_name = "shader/default.xml";
    KeyPtr shader_key_ptr = Key::Find(shader_key_name.c_str());
    if(shader_key_ptr == NULL)
    {
        Shader*shader = GNEW(Shader);
        CHECK(shader);
        shader->Load(GLoad(shader_key_name.c_str()));
        shader_key_ptr = GNEW(Key(shader_key_name.c_str(), shader));
        CHECK(shader_key_ptr);
    }
    mKeys.push_back(shader_key_ptr);
    mQuadPtr->SetShader(dynamic_cast<Shader*>(shader_key_ptr->Ptr()),"p0");

    // build the vertex buffer
    F32 x = 0.0f, y = 0.0f, w = 256, h = 256;
    DVT vertexes[] =
    {
        {x,		y,		0,		0,		0},
        {x+w,	y,		0,		1,		0},
        {x+w,	y+h,	0,		1,		1},
        {x,		y+h,	0,		0,		1},
    };
    VertexBufferPtr vb_ptr = GNEW(VertexBuffer);
    CHECK(vb_ptr);
    {
        GDataPtr vd_ptr = GNEW(GData);
        CHECK(vd_ptr);
        vd_ptr->Size(3*sizeof(U32) + 3*sizeof(U8) + sizeof(vertexes));
        U8*data_ptr = (U8*)vd_ptr->Ptr();
        *(U32*)data_ptr = MAKEFOURCC('G','V','B','O');
        data_ptr += sizeof(U32);
        *(U32*)data_ptr = sizeof(vertexes)/sizeof(DVT);
        data_ptr += sizeof(U32);
        *(U32*)data_ptr = sizeof(DVT);
        data_ptr += sizeof(U32);
        *(U8*)data_ptr = 2;
        data_ptr += sizeof(U8);
        *(U8*)data_ptr = VertexBuffer::VT_3F;
        data_ptr += sizeof(U8);
        *(U8*)data_ptr = VertexBuffer::VT_2F;
        data_ptr += sizeof(U8);
        ::memcpy(data_ptr, vertexes, sizeof(vertexes));
        data_ptr += sizeof(vertexes);
        vb_ptr->Load(vd_ptr.Ptr());
    }
    mQuadPtr->SetVertexBuffer(vb_ptr.Ptr());

    // build the index
    const U16 indexes[] = { 3, 0, 2, 2, 0, 1 };
    IndexBufferPtr ib_ptr = GNEW(IndexBuffer);
    CHECK(ib_ptr);
    {
        GDataPtr id_ptr = GNEW(GData);
        CHECK(id_ptr);
        id_ptr->Size(3*sizeof(U32) + sizeof(indexes));
        U8*data_ptr = (U8*)id_ptr->Ptr();
        *(U32*)data_ptr = MAKEFOURCC('G','I','B','O');
        data_ptr += sizeof(U32);
        *(U32*)data_ptr = sizeof(indexes)/sizeof(U16);
        data_ptr += sizeof(U32);
        *(U32*)data_ptr = sizeof(U16);
        data_ptr += sizeof(U32);
        ::memcpy(data_ptr, &indexes[0], sizeof(indexes));
        data_ptr += sizeof(indexes);
        ib_ptr->Load(id_ptr.Ptr());
    }
    mQuadPtr->SetIndexBuffer(ib_ptr.Ptr());

    // build the bounding box
    BoundingBox box;
    box.set(MAX_F32,MAX_F32,MAX_F32,MIN_F32,MIN_F32,MIN_F32);
    for(U32 i = 0; i < sizeof(vertexes)/sizeof(DVTN); i++)box.expand(vertexes[i].point);
    mQuadPtr->SetBox(box);

    UNGUARD;
}
Ejemplo n.º 12
0
const bool BoundingBox::contains(const BoundingBox &box) const
{
    return(box.minCorner() >= this->minCorner() &&
           box.maxCorner() <= this->maxCorner());
}
Ejemplo n.º 13
0
bool
BridgeDetector::detect_angle()
{
    if (this->_edges.empty() || this->_anchors.empty()) return false;
    
    /*  Outset the bridge expolygon by half the amount we used for detecting anchors;
        we'll use this one to clip our test lines and be sure that their endpoints
        are inside the anchors and not on their contours leading to false negatives. */
    Polygons clip_area;
    offset(this->expolygon, &clip_area, +this->extrusion_width/2);
    
    /*  we'll now try several directions using a rudimentary visibility check:
        bridge in several directions and then sum the length of lines having both
        endpoints within anchors */
    
    // we test angles according to configured resolution
    std::vector<double> angles;
    for (int i = 0; i <= PI/this->resolution; ++i)
        angles.push_back(i * this->resolution);
    
    // we also test angles of each bridge contour
    {
        Polygons pp = this->expolygon;
        for (Polygons::const_iterator p = pp.begin(); p != pp.end(); ++p) {
            Lines lines = p->lines();
            for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line)
                angles.push_back(line->direction());
        }
    }
    
    /*  we also test angles of each open supporting edge
        (this finds the optimal angle for C-shaped supports) */
    for (Polylines::const_iterator edge = this->_edges.begin(); edge != this->_edges.end(); ++edge) {
        if (edge->first_point().coincides_with(edge->last_point())) continue;
        angles.push_back(Line(edge->first_point(), edge->last_point()).direction());
    }
    
    // remove duplicates
    double min_resolution = PI/180.0;  // 1 degree
    std::sort(angles.begin(), angles.end());
    for (size_t i = 1; i < angles.size(); ++i) {
        if (Slic3r::Geometry::directions_parallel(angles[i], angles[i-1], min_resolution)) {
            angles.erase(angles.begin() + i);
            --i;
        }
    }
    /*  compare first value with last one and remove the greatest one (PI) 
        in case they are parallel (PI, 0) */
    if (Slic3r::Geometry::directions_parallel(angles.front(), angles.back(), min_resolution))
        angles.pop_back();
    
    BridgeDirectionComparator bdcomp(this->extrusion_width);
    double line_increment = this->extrusion_width;
    bool have_coverage = false;
    for (std::vector<double>::const_iterator angle = angles.begin(); angle != angles.end(); ++angle) {
        Polygons my_clip_area = clip_area;
        ExPolygons my_anchors = this->_anchors;
        
        // rotate everything - the center point doesn't matter
        for (Polygons::iterator it = my_clip_area.begin(); it != my_clip_area.end(); ++it)
            it->rotate(-*angle, Point(0,0));
        for (ExPolygons::iterator it = my_anchors.begin(); it != my_anchors.end(); ++it)
            it->rotate(-*angle, Point(0,0));
    
        // generate lines in this direction
        BoundingBox bb;
        for (ExPolygons::const_iterator it = my_anchors.begin(); it != my_anchors.end(); ++it)
            bb.merge((Points)*it);
        
        Lines lines;
        for (coord_t y = bb.min.y; y <= bb.max.y; y += line_increment)
            lines.push_back(Line(Point(bb.min.x, y), Point(bb.max.x, y)));
        
        Lines clipped_lines;
        intersection(lines, my_clip_area, &clipped_lines);
        
        // remove any line not having both endpoints within anchors
        for (size_t i = 0; i < clipped_lines.size(); ++i) {
            Line &line = clipped_lines[i];
            if (!Slic3r::Geometry::contains(my_anchors, line.a)
                || !Slic3r::Geometry::contains(my_anchors, line.b)) {
                clipped_lines.erase(clipped_lines.begin() + i);
                --i;
            }
        }
        
        std::vector<double> lengths;
        double total_length = 0;
        for (Lines::const_iterator line = clipped_lines.begin(); line != clipped_lines.end(); ++line) {
            double len = line->length();
            lengths.push_back(len);
            total_length += len;
        }
        if (total_length) have_coverage = true;
        
        // sum length of bridged lines
        bdcomp.dir_coverage[*angle] = total_length;
        
        /*  The following produces more correct results in some cases and more broken in others.
            TODO: investigate, as it looks more reliable than line clipping. */
        // $directions_coverage{$angle} = sum(map $_->area, @{$self->coverage($angle)}) // 0;
        
        // max length of bridged lines
        bdcomp.dir_avg_length[*angle] = !lengths.empty()
            ? *std::max_element(lengths.begin(), lengths.end())
            : 0;
    }
    
    // if no direction produced coverage, then there's no bridge direction
    if (!have_coverage) return false;
    
    // sort directions by score
    std::sort(angles.begin(), angles.end(), bdcomp);
    
    this->angle = angles.front();
    if (this->angle >= PI) this->angle -= PI;
    
    #ifdef SLIC3R_DEBUG
    printf("  Optimal infill angle is %d degrees\n", (int)Slic3r::Geometry::rad2deg(this->angle));
    #endif
    
    return true;
}
Ejemplo n.º 14
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
TEST(BoxGeneratorTest, GenerateSimple)
{
    // From min/max
    {
        BoxGenerator gen;
        gen.setMinMax(Vec3d(10, 20, 30), Vec3d(20, 40, 60));

        BuilderTrisQuads builder;
        gen.generate(&builder);
        BoundingBox bb = builder.vertexBoundingBox();
        EXPECT_DOUBLE_EQ(10, bb.min().x());
        EXPECT_DOUBLE_EQ(20, bb.min().y());
        EXPECT_DOUBLE_EQ(30, bb.min().z());
        EXPECT_DOUBLE_EQ(20, bb.max().x());
        EXPECT_DOUBLE_EQ(40, bb.max().y());
        EXPECT_DOUBLE_EQ(60, bb.max().z());

        EXPECT_EQ(0, builder.triCount());
        EXPECT_EQ(6, builder.quadCount());
    }

    // From origin and extent
    {
        BoxGenerator gen;
        gen.setOriginAndExtent(Vec3d(10, 20, 30), Vec3d(100, 200, 300));

        BuilderTrisQuads builder;
        gen.generate(&builder);
        BoundingBox bb = builder.vertexBoundingBox();
        EXPECT_DOUBLE_EQ(10,  bb.min().x());
        EXPECT_DOUBLE_EQ(20,  bb.min().y());
        EXPECT_DOUBLE_EQ(30,  bb.min().z());
        EXPECT_DOUBLE_EQ(110, bb.max().x());
        EXPECT_DOUBLE_EQ(220, bb.max().y());
        EXPECT_DOUBLE_EQ(330, bb.max().z());
    }

    // From center and extent
    {
        BoxGenerator gen;
        gen.setCenterAndExtent(Vec3d(100, 200, 300), Vec3d(10, 20, 30));

        BuilderTrisQuads builder;
        gen.generate(&builder);
        BoundingBox bb = builder.vertexBoundingBox();
        EXPECT_DOUBLE_EQ(95,  bb.min().x());
        EXPECT_DOUBLE_EQ(190, bb.min().y());
        EXPECT_DOUBLE_EQ(285,  bb.min().z());
        EXPECT_DOUBLE_EQ(105, bb.max().x());
        EXPECT_DOUBLE_EQ(210, bb.max().y());
        EXPECT_DOUBLE_EQ(315, bb.max().z());
    }
}
Ejemplo n.º 15
0
void
process_goturn_detection(Mat *img, double time_stamp)
{
	char string1[128];
	CvFont font;
	bool recovery = false;
	static int cont = 0;
	static int first = 0;
	int step = 10;

	//cv::Mat mat_image=cvarrToMat(&img);
	static Mat prev_image;
	prev_image = img->clone();
	if(box.x1_ != -1.0)
	{

		tracker.Track(*img, &regressor, &box);
		if (cont > 30)
		{
			calculate_box_average(box, last_track, img, step, cont);
//			recovery = true;
		}
		//Apenas para publicar-ainda falta definir
		average_box_confidence = 1.0;

		last_track[(cont%30)].prev_image = prev_image;
		last_track[(cont%30)].prev_box = box;
		box.DrawBoundingBox(img);
		cont++;

		tracker.Init(*img, box, &regressor);

	}

	cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, .4, .5, 0, 1, 8);
//	cvRectangle(&prev_image, cvPoint(0, 0), cvPoint(img.width, 50), CV_RGB(0, 0, 255), CV_FILLED, 8, 0);
//	cvPutText(&prev_image.data, string1, cvPoint(25, 25), &font, CV_RGB(255, 255, 255));
	// draw the box
	sprintf(string1, "Time:%.2f, FPS:%d", time_stamp, disp_last_fps);
	cv::Size s = img->size();
	cv::Point textOrg(25,25);
	cv::rectangle(*img, cv::Point(0, 0), cv::Point(s.width, 50), Scalar::all(0), -1);
	cv::putText(*img, string1,textOrg,FONT_HERSHEY_SIMPLEX, 0.4,Scalar::all(255),1,8);

	cv::imshow(window_name, *img);

	char c = cv::waitKey(2);

	switch (c)
	{
	case 'r':

		CvRect rect;

		if (getBBFromUser(img, rect, window_name) == 0)
		{
			return;
		}

		box.x1_ = rect.x;
		box.y1_ = rect.y;
		box.x2_ = rect.x+rect.width;
		box.y2_ = rect.y+rect.height;
		last_track[(cont%30)].prev_image = prev_image;
		last_track[(cont%30)].prev_box = box;
		cont++;
		tracker.Init(*img, box, &regressor);
//		first = 1;
//		tracker.Track(*img, &regressor, &box);
		break;

	case 'q':
		exit(0);
	}
		// Track and estimate the bounding box location.

}
Ejemplo n.º 16
0
bool DynamicNavigationMesh::Build(const BoundingBox& boundingBox)
{
    URHO3D_PROFILE(BuildPartialNavigationMesh);

    if (!node_)
        return false;

    if (!navMesh_)
    {
        URHO3D_LOGERROR("Navigation mesh must first be built fully before it can be partially rebuilt");
        return false;
    }

    if (!node_->GetWorldScale().Equals(Vector3::ONE))
        URHO3D_LOGWARNING("Navigation mesh root node has scaling. Agent parameters may not work as intended");

    BoundingBox localSpaceBox = boundingBox.Transformed(node_->GetWorldTransform().Inverse());

    float tileEdgeLength = (float)tileSize_ * cellSize_;

    Vector<NavigationGeometryInfo> geometryList;
    CollectGeometries(geometryList);

    int sx = Clamp((int)((localSpaceBox.min_.x_ - boundingBox_.min_.x_) / tileEdgeLength), 0, numTilesX_ - 1);
    int sz = Clamp((int)((localSpaceBox.min_.z_ - boundingBox_.min_.z_) / tileEdgeLength), 0, numTilesZ_ - 1);
    int ex = Clamp((int)((localSpaceBox.max_.x_ - boundingBox_.min_.x_) / tileEdgeLength), 0, numTilesX_ - 1);
    int ez = Clamp((int)((localSpaceBox.max_.z_ - boundingBox_.min_.z_) / tileEdgeLength), 0, numTilesZ_ - 1);

    unsigned numTiles = 0;

    for (int z = sz; z <= ez; ++z)
    {
        for (int x = sx; x <= ex; ++x)
        {
            dtCompressedTileRef existing[TILECACHE_MAXLAYERS];
            const int existingCt = tileCache_->getTilesAt(x, z, existing, maxLayers_);
            for (int i = 0; i < existingCt; ++i)
            {
                unsigned char* data = 0x0;
                if (!dtStatusFailed(tileCache_->removeTile(existing[i], &data, 0)) && data != 0x0)
                    dtFree(data);
            }

            TileCacheData tiles[TILECACHE_MAXLAYERS];
            int layerCt = BuildTile(geometryList, x, z, tiles);
            for (int i = 0; i < layerCt; ++i)
            {
                dtCompressedTileRef tileRef;
                int status = tileCache_->addTile(tiles[i].data, tiles[i].dataSize, DT_COMPRESSEDTILE_FREE_DATA, &tileRef);
                if (dtStatusFailed((dtStatus)status))
                {
                    dtFree(tiles[i].data);
                    tiles[i].data = 0x0;
                }
                else
                {
                    tileCache_->buildNavMeshTile(tileRef, navMesh_);
                    ++numTiles;
                }
            }
        }
    }

    URHO3D_LOGDEBUG("Rebuilt " + String(numTiles) + " tiles of the navigation mesh");
    return true;
}
Ejemplo n.º 17
0
const Vector3F Geometry::boundingCenter() const
{
	BoundingBox box = calculateBBox();
	return box.center();
}
Ejemplo n.º 18
0
/*!
 * \brief Static function for box intersection. Return false if they do not
 * intersect. 
 *
 * \param box_A Bounding box A.
 *
 * \param box_B Bounding box B.
 *
 * \param intersection A bounding box that is equivalent to the inersection of
 * box A and box B. Box A and B can be provided in any order (the
 * intersection of box A with box B is equal to the intersection of box B with
 * box A).
 *
 * \return Return true if the boxes intersect. False if they do not.
 */
bool BoundingBox::intersectBoxes( const BoundingBox& box_A,
				  const BoundingBox& box_B,
				  BoundingBox& intersection)
{
    Teuchos::Tuple<double,6> bounds_A = box_A.getBounds();
    Teuchos::Tuple<double,6> bounds_B = box_B.getBounds();

    double x_min, y_min, z_min, x_max, y_max, z_max;

    // Test for no overlap in X.
    if ( bounds_A[0] > bounds_B[3] || bounds_A[3] < bounds_B[0] )
    {
	return false;
    }
    // Test for no overlap in Y.
    if ( bounds_A[1] > bounds_B[4] || bounds_A[4] < bounds_B[1] )
    {
	return false;
    }
    // Test for no overlap in Z.
    if ( bounds_A[2] > bounds_B[5] || bounds_A[5] < bounds_B[2] )
    {
	return false;
    }

    // Get overlap in X.
    if ( bounds_A[0] > bounds_B[0] )
    {
	x_min = bounds_A[0];
    }
    else
    {
	x_min = bounds_B[0];
    }
    if ( bounds_A[3] > bounds_B[3] )
    {
	x_max = bounds_B[3];
    }
    else
    {
	x_max = bounds_A[3];
    }

    // Get overlap in Y.
    if ( bounds_A[1] > bounds_B[1] )
    {
	y_min = bounds_A[1];
    }
    else
    {
	y_min = bounds_B[1];
    }
    if ( bounds_A[4] > bounds_B[4] )
    {
	y_max = bounds_B[4];
    }
    else
    {
	y_max = bounds_A[4];
    }

    // Get overlap in Z.
    if ( bounds_A[2] > bounds_B[2] )
    {
	z_min = bounds_A[2];
    }
    else
    {
	z_min = bounds_B[2];
    }
    if ( bounds_A[5] > bounds_B[5] )
    {
	z_max = bounds_B[5];
    }
    else
    {
	z_max = bounds_A[5];
    }

    intersection = BoundingBox( x_min, y_min, z_min, x_max, y_max, z_max );
    return true;
}
Ejemplo n.º 19
0
/** This routine creates the text for the slider value and sets the correct position
  relative to the position indicator.
  @param xPos position of slider value string
*/
ref_ptr<Geode> OSGVruiSlider::createText(float xPos)
{

    if (!numberText)
    {
        textNode = new Geode();

        numberText = new Text();
        numberText->setDataVariance(Object::DYNAMIC);
        numberText->setFont(OSGVruiPresets::getFontFile());
        numberText->setDrawMode(Text::TEXT);
        numberText->setColor(Vec4(1.0f, 1.0f, 1.0f, 1.0f));

        numberText->setAlignment(Text::CENTER_BASE_LINE);
        numberText->setLayout(Text::LEFT_TO_RIGHT);
        numberText->setAxisAlignment(Text::XY_PLANE);

        sliderDialSize = slider->getDialSize();
        numberText->setCharacterSize(sliderDialSize * 2.0f);

        textNode->setStateSet(OSGVruiPresets::getStateSetCulled(coUIElement::YELLOW));
        textNode->addDrawable(numberText.get());
    }

    if (sliderDialSize != slider->getDialSize())
    {
        sliderDialSize = slider->getDialSize();
        numberText->setCharacterSize(sliderDialSize * 2.0f);
    }

    char number[200];
    float value = slider->getValue();
    int precision = slider->getPrecision();

    if (slider->isInteger())
    {
        sprintf(number, "%d", (int)value);
    }
    else
    {
        sprintf(number, "%.*f", precision, value);
    }

    numberText->setText(number, String::ENCODING_UTF8);
    numberText->dirtyBound();

#if OSG_VERSION_GREATER_OR_EQUAL(3, 3, 2)
    BoundingBox stringBoundingBox = numberText->getBoundingBox();
#else
    BoundingBox stringBoundingBox = numberText->getBound();
#endif
    Vec3 position;

    float myWidth = slider->getWidth();
    float dialSize = slider->getDialSize();

    float xSize = stringBoundingBox.xMax() - stringBoundingBox.xMin();

    if (xPos - xSize + dialSize < 0.0f)
    {
        position = Vec3(xSize - xPos - dialSize, 2.0f * dialSize, 0.0f);
    }
    else if (xPos + xSize - dialSize > myWidth)
    {
        position = Vec3(myWidth - xPos - xSize + dialSize, 2.0f * dialSize, 0.0f);
    }
    else
    {
        position = Vec3(0.0f, 2.0f * dialSize, 0.0f);
    }

    numberText->setPosition(position);

    return textNode;
}
Ejemplo n.º 20
0
void LabelsRenderer::renderGraphNodesLabels(Graph *graph, const Camera &camera, const Color &selectionColor) {

  initFont();

  BooleanProperty *viewSelection = graph->getProperty<BooleanProperty>("viewSelection");
  ColorProperty *viewLabelColor = graph->getProperty<ColorProperty>("viewLabelColor");
  StringProperty *viewLabel = graph->getProperty<StringProperty>("viewLabel");

  Vec4i viewport = camera.getViewport();

  vector<vector<Vec2f> > renderedLabelsScrRect;
  vector<BoundingBox> renderedLabelsScrBB;

  NVGcontext* vg = NanoVGManager::instance()->getNanoVGContext();

  nvgBeginFrame(vg, camera.getViewport()[0], camera.getViewport()[1], camera.getViewport()[2], camera.getViewport()[3], 1.0);

  for (vector<node>::iterator it = _labelsToRender[graph].begin() ; it != _labelsToRender[graph].end() ; ++it) {

    if (_nodeLabelAspectRatio[graph].find(*it) == _nodeLabelAspectRatio[graph].end()) {
      continue;
    }

    BoundingBox nodeBB = labelBoundingBoxForNode(graph, *it);

    BoundingBox textBB = getLabelRenderingBoxScaled(nodeBB, _nodeLabelAspectRatio[graph][*it]);

    if (!_labelsScaled) {

      adjustTextBoundingBox(textBB, camera, _minSize, _maxSize, _nodeLabelNbLines[graph][*it]);
    }

    bool canRender = true;

    if (_occlusionTest) {

      if (!camera.hasRotation()) {
        BoundingBox textScrBB;
        textScrBB.expand(Vec3f(computeScreenPos(camera.transformMatrixBillboard(), viewport, textBB[0]), 0));
        textScrBB.expand(Vec3f(computeScreenPos(camera.transformMatrixBillboard(), viewport, textBB[1]), 0));

        for (size_t i = 0 ; i < renderedLabelsScrBB.size() ; ++i) {
          if (textScrBB.intersect(renderedLabelsScrBB[i])) {
            canRender = false;
            break;
          }
        }

        if (canRender) {
          renderedLabelsScrBB.push_back(textScrBB);
        }

      } else {
        vector<Vec2f> textScrRect;
        textScrRect.push_back(computeScreenPos(camera.transformMatrix(), viewport, textBB[0]));
        textScrRect.push_back(computeScreenPos(camera.transformMatrix(), viewport, Vec3f(textBB[0][0]+textBB.width(), textBB[0][1], textBB[0][2])));
        textScrRect.push_back(computeScreenPos(camera.transformMatrix(), viewport, textBB[1]));
        textScrRect.push_back(computeScreenPos(camera.transformMatrix(), viewport, Vec3f(textBB[0][0], textBB[0][1]+textBB.height(), textBB[0][2])));

        for (size_t i = 0 ; i < renderedLabelsScrRect.size() ; ++i) {
          if (convexPolygonsIntersect(textScrRect, renderedLabelsScrRect[i])) {
            canRender = false;
            break;
          }
        }

        if (canRender) {
          renderedLabelsScrRect.push_back(textScrRect);
        }
      }
    }

    if (canRender) {

      Vec2f textBBMinScr = computeScreenPos(camera.transformMatrix(), viewport, textBB[0]);
      Vec2f textBBMaxScr = computeScreenPos(camera.transformMatrix(), viewport, textBB[1]);
      BoundingBox bb;
      bb.expand(Vec3f(textBBMinScr[0], viewport[3] - textBBMinScr[1]));
      bb.expand(Vec3f(textBBMaxScr[0], viewport[3] - textBBMaxScr[1]));

      renderText(vg, viewLabel->getNodeValue(*it), bb, viewSelection->getNodeValue(*it) ? selectionColor : viewLabelColor->getNodeValue(*it));

    }

  }

  nvgEndFrame(vg);
}
Ejemplo n.º 21
0
void ImagePane::paintEvent(QPaintEvent* /*event*/)
{
    QPainter painter(this);

    //draw the transformed version of the text-object image
    painter.drawImage(0, 0, transformedImage);

    //then we draw the bounding boxes
    //TODO inscriptions with at least one graph are a different color (?)

    //in case index numbers are visible, set font
    QFont font;
    font.setPixelSize(30/zoom); //TODO make font size dependent on resolution
    painter.setFont(font);
    QPen pen;
    pen.setWidth(0);
    pen.setColor(Qt::red);
    painter.setPen(pen);
    //make a list of bounding boxes according to current mode
    BoxList currentBoxList; //this is a list of all boxes
    currentBoxList.clear();
    switch(mode)
    {
    case SURFACE:
        currentBoxList.append(*surf); //list of one item, consting of the surface bounding box
        break;
    case INSCRIPTION:
        for(int i=0; i < surf->inscriptionCount(); i++)
            currentBoxList.insertBox(surf->inscrAt(i), i);
        break;
    case GRAPH:
        for(int i=0; i < surf->ptrInscrAt(currentInscrIndex)->count(); i++)
            currentBoxList.insertBox(surf->ptrInscrAt(currentInscrIndex)->at(i), i);
        break;
    default:
       break;
    }
    //iterate through the list of bounding boxes
    for (int i=0; i<currentBoxList.size(); i++)
    {
        BoundingBox currentBox = currentBoxList.at(i);

        //the bounding boxes need to be rotated and scaled
        QTransform boxTransform; //identity matrix
        //first we need to handle the bounding box's own rotation
        //by inverting the true matrix that was applied to the image
        //at the time each bounding box was created
        //(note: we don't need to worry about scale, as we took account of that
        //when the bounding box was created)
        boxTransform.rotate(currentBox.getRotation());
        boxTransform = QImage::trueMatrix(boxTransform,
                                          currentImage.width(), currentImage.height());
        boxTransform = boxTransform.inverted();
	
        //then we compound the above matrix with the current transformation of the image
        QTransform imageTrueTransform = QImage::trueMatrix(transform,
                                                           currentImage.width(), currentImage.height());
        painter.setWorldTransform(boxTransform * imageTrueTransform);
        //now draw the box
        //pen color is red; set the pen-color to green if this is the current box.
        if(i==currentBoxIndex)
        {
            QPen pen;
            pen.setWidth(0);
            pen.setColor(Qt::green);
            painter.setPen(pen);
        }
        painter.drawRect(currentBox);
        //and add an (optional) index number
        if(indexNumbersVisible)
        {
            painter.drawText(currentBox.left(), currentBox.top(), 50/zoom, 50/zoom,
                             Qt::AlignBottom,  QString("%1").arg(i+1)); //visible index, so base = 1, not zero
        }
        //return pen color to red (might be green)
        QPen pen;
        pen.setWidth(0);
        pen.setColor(Qt::red);
        painter.setPen(Qt::red);
    }

    //if label is not resized, it will stay large on zoom out
    //resulting in misleading / redundant scroll bars
    resize(transformedImage.size()); // keep label same size as image
}
Ejemplo n.º 22
0
//===========================================================================
void CellDivision::constructCells()
//===========================================================================
{
    // @@@ NOTE
    //
    // This implementation depends upon using bounding boxes that are
    // aligned with the principal axis and box-shaped.

    // First we check if big_box_ is valid. @jbt
    if (!big_box_.valid()) {
        MESSAGE("Big box is invalid - returning empty cell vector.");
        cells_.clear();
        return;
    }

    if (dim_ < 1) {
        MESSAGE("Incorrect number of space dimensions.");
        cells_.clear();
        return;
    }

    // We partition space into cells.
    
    makeCoords();

    double tol = 1.0e-9;  // VSK, 082017. To avoid loosing surfaces in
    // planar cases
    int ncells = ncells_[0];
    for (int i = 1; i < dim_; ++i)
        ncells *= ncells_[i];
    cells_.resize(ncells);
    Point low = big_box_.low();
    Point len = big_box_.high() - low;
    cell_delta_.resize(dim_);
    for (int i = 0; i < dim_; ++i)
        cell_delta_[i] = len[i] / ncells_[i];

    Point corner;
    corner.resize(dim_);
    for (int i = 0; i < ncells; ++i) {
        for (int dd = 0; dd < dim_; ++dd) {
            corner[dd] = low[dd] + coords_[i][dd] * cell_delta_[dd];
        }
        cells_[i].setBox(BoundingBox(corner, corner + cell_delta_));
    }

    // Now that we have the cells, we check every face, and add its pointer
    // to every cell overlapping its bounding box.
    for (size_t f=0; f<faces_.size(); ++f) {
        BoundingBox b = faces_[f]->boundingBox();
        for (int i = 0; i < ncells; ++i) {
	  if (b.overlaps(cells_[i].box(), tol)) {
                cells_[i].addFace(faces_[f]);
                cells_[i].addFaceBox(b);
            }
        }
    }


//    // The following code depends on dimensionality 3 - commenting out. @jbt
//    int i, j, k;
//
//    // We partition space into cells.
//    cells_.resize(ncellsx_*ncellsy_*ncellsz_);
//    Point low = big_box_.low();
//    Point len = big_box_.high() - low;
//    cell_delta_ = Point(len[0]/ncellsx_, len[1]/ncellsy_, len[2]/ncellsz_);
//    const Point& delta = cell_delta_;
//
//    double x = low[0];
//    double y = low[1];
//    double z = low[2];
//    Point corner;
//
//    for (i=0; i<ncellsx_; ++i) {
//        y = low[1];
//        for (j=0; j<ncellsy_; ++j) {
//            z = low[2];
//            for (k=0; k<ncellsz_; ++k) {
//                corner.setValue(x, y, z);
//                cells_[i + j*ncellsx_ + k*ncellsx_*ncellsy_]
//                    .setBox(BoundingBox(corner, corner + delta));
//                z += delta[2];
//            }
//            y += delta[1];
//        }
//        x += delta[0];
//    }
//
//    int x1, x2, y1, y2, z1, z2;
//    Point lo, hi;
//    // Now that we have the cells, we check every face, and add its pointer
//    // to every cell overlapping its bounding box.
//    for (size_t f=0; f<faces_.size(); ++f) {
//        BoundingBox b = faces_[f]->boundingBox();
//        lo = b.low();
//        hi = b.high();
//        cellContaining(lo, x1, y1, z1);
//        cellContaining(hi, x2, y2, z2);
//        for (i=x1; i<=x2; ++i)
//            for (j=y1; j<=y2; ++j)
//                for (k=z1; k<=z2; ++k)
//                {
//                    cells_[i + j*ncellsx_ + k*ncellsx_*ncellsy_].addFace(faces_[f]);
//                    cells_[i + j*ncellsx_ + k*ncellsx_*ncellsy_].addFaceBox(b);
//                }
//    }
//
//#ifdef DEBUG_CELLS
//    for (i=0; i<ncellsx_*ncellsy_*ncellsz_; ++i) {
//        cout << "Cell " << i << " has "
//             << cells_[i].num_faces() << " faces ";
//        for (j=0; j<cells_[i].num_faces(); ++j)
//            cout << cells_[i].face(j)->GetId() << " ";
//        cout << endl;
//    }
//#endif

}
Ejemplo n.º 23
0
void isab::Faker::decodedMapRequest(int len, const uint8* data,  
                                    uint32 dst,
                                    int /*latOffset*/, int /*lonOffset*/, 
                                    int /*hdgOffset*/, int /*spdOffset*/)
{
   // decode data
   Buffer req(len);
   req.writeNextByteArray(data, len);
   BoundingBox* bb = BoundingBox::deserialize(&req);
   uint16 width = req.readNextUnaligned16bit();
   uint16 height = req.readNextUnaligned16bit();
   uint16 vbw = req.readNextUnaligned16bit();
   uint16 vbh = req.readNextUnaligned16bit();
   vbh = vbh;
   vbw = vbw;
   DBG("decodedMapRequest: width: %d, height: %d", width, height);
   //select map file
#ifdef __SYMBIAN32__
   const char* path = getGlobalData().m_writable_files_path;
#else
   const char* path = LINUX_BASE_PATH;
#endif
#define SCNCRD(fmtspec) "(%"fmtspec",%"fmtspec")"
   const char* scfmt = SCNCRD(SCNd32)SCNCRD(SCNd32)SCNCRD("d")SCNCRD(SCNd32);

   int32 tlat = 0, tlon = 0, blat = 0, blon = 0, rww = 0, rwh = 0;
   int w = 0, h = 0;

   char filename[256] = {0};
   const char* type = NULL;
   switch(bb->getBoxType()){
   case BoundingBox::invalidBox: //error
      break;
   case BoundingBox::diameterBox: //zoom to turn, position, ...
      {
         DBG("DiameterBox request");
         DiameterBox* db = static_cast<DiameterBox*>(bb);
         const char * const types[] = {"orig", "dest"};
         char tmp[256] = {0};
         for(size_t a = 0; (!type) && (a < sizeof(types)/sizeof(*types)); ++a){
            snprintf(tmp, sizeof(tmp) - 1, "%s%dx%d%sdata.txt",
                     path, width, height, types[a]);
            DBG("Testing file '%s' for coords (%"PRId32",%"PRId32")", tmp, 
                db->getLat(), db->getLon());
            FILE* dataf = fopen(tmp, "r");
            if(dataf){
               DBG("'%s' opened OK", tmp);
               tlat = tlon = blat = blon = rww = rwh = w = h = 0;
               if(8 == fscanf(dataf, scfmt, &tlat, &tlon, &blat, &blon, 
                              &rww, &rwh, &w, &h)){
                  DBG("(%"PRId32",%"PRId32")(%"PRId32",%"PRId32")"
                      "(%"PRId32",%"PRId32")(%d,%d)",
                      tlat, tlon, blat, blon,
                      rww, rwh, w, h);
                  if(BoxBox(tlat, tlon, 
                            blat, blon).Contains(db->getLat(), db->getLon())){
                     DBG("Contains(%"PRId32",%"PRId32")", db->getLat(), db->getLon());
                     type = types[a];
                  }
               }
               fclose(dataf);
            }
         }
         if(type == NULL){
            type = "route";
         }
      }
      break;
   case BoundingBox::boxBox:  //zoom?
   case BoundingBox::vectorBox: //tracking
   case BoundingBox::routeBox: //zoom to route
      type = "route";
   }

   if(type != NULL){
      snprintf(filename, sizeof(filename) - 1, "%s%dx%d%s.gif", 
               path, width, height, type);
      DBG("opening file %s", filename);
      FILE* mapfile = fopen(filename, "rb");
      if(mapfile){
         snprintf(filename, sizeof(filename) - 1, "%s%dx%d%sdata.txt",
                  path, width, height, type);
         FILE* datafile = fopen(filename, "r");
         if(datafile && (8 == fscanf(datafile, scfmt, &tlat, &tlon, 
                                     &blat, &blon, &rww, &rwh, &w, &h))){
            Buffer reply(5*1024);
            reply.writeNextUnaligned32bit(tlat);
            reply.writeNextUnaligned32bit(tlon);
            reply.writeNextUnaligned32bit(blat);
            reply.writeNextUnaligned32bit(blon);
            reply.writeNextUnaligned16bit(w);
            reply.writeNextUnaligned16bit(h);
            reply.writeNextUnaligned32bit(rww);
            reply.writeNextUnaligned32bit(rwh);
            int lengthpos = reply.getWritePos();
            reply.writeNextUnaligned32bit(0); //buffer size
            reply.writeNextUnaligned16bit(GIF);
            int start = reply.getWritePos(); //buffer start
            
            const size_t BUFFER_LEN = 1024;
            uint8* buffer = new uint8[BUFFER_LEN];
            size_t len = 0;
            while(BUFFER_LEN == (len = fread(buffer, sizeof(*buffer), 
                                             BUFFER_LEN, mapfile))){
               reply.writeNextByteArray(buffer, len);
            }
            reply.writeNextByteArray(buffer, len);
            delete[] buffer;
            int end = reply.setWritePos(lengthpos);
            reply.writeNextUnaligned32bit(end - start);
            m_interface->
               NavServerComConsumerPublicRef().mapReply(reply.getLength(), 
                                                        reply.accessRawData(0),
                                                        dst);
            fclose(datafile);
         } else {  //data error
            m_interface->sendError(Nav2Error::NSC_OPERATION_NOT_SUPPORTED,dst);
         }
         fclose(mapfile);
      } else {
         m_interface->sendError(Nav2Error::NSC_OPERATION_NOT_SUPPORTED, dst);
      }
   } else {
      m_interface->sendError(Nav2Error::NSC_OPERATION_NOT_SUPPORTED, dst);
   }      
   delete bb;
}
Ejemplo n.º 24
0
double Area(const BoundingBox& bb){
  return (bb.y2() - bb.y1())*(bb.x2() - bb.x1());
}
Ejemplo n.º 25
0
void NavigationMesh::GetTileGeometry(NavigationBuildData& build, Vector<NavigationGeometryInfo>& geometryList, BoundingBox& box)
{
    Matrix3x4 inverse = node_->GetWorldTransform().Inverse();
    
    for (unsigned i = 0; i < geometryList.Size(); ++i)
    {
        if (box.IsInsideFast(geometryList[i].boundingBox_) != OUTSIDE)
        {
            const Matrix3x4& transform = geometryList[i].transform_;
            
            if (geometryList[i].component_->GetType() == OffMeshConnection::GetTypeStatic())
            {
                OffMeshConnection* connection = static_cast<OffMeshConnection*>(geometryList[i].component_);
                Vector3 start = inverse * connection->GetNode()->GetWorldPosition();
                Vector3 end = inverse * connection->GetEndPoint()->GetWorldPosition();
                
                build.offMeshVertices_.Push(start);
                build.offMeshVertices_.Push(end);
                build.offMeshRadii_.Push(connection->GetRadius());
                /// \todo Allow to define custom flags
                build.offMeshFlags_.Push(0x1);
                build.offMeshAreas_.Push(0);
                build.offMeshDir_.Push(connection->IsBidirectional() ? DT_OFFMESH_CON_BIDIR : 0);
                continue;
            }
            
            CollisionShape* shape = dynamic_cast<CollisionShape*>(geometryList[i].component_);
            if (shape)
            {
                switch (shape->GetShapeType())
                {
                case SHAPE_TRIANGLEMESH:
                    {
                        Model* model = shape->GetModel();
                        if (!model)
                            continue;
                        
                        unsigned lodLevel = shape->GetLodLevel();
                        for (unsigned j = 0; j < model->GetNumGeometries(); ++j)
                            AddTriMeshGeometry(build, model->GetGeometry(j, lodLevel), transform);
                    }
                    break;
                    
                case SHAPE_CONVEXHULL:
                    {
                        ConvexData* data = static_cast<ConvexData*>(shape->GetGeometryData());
                        if (!data)
                            continue;
                        
                        unsigned numVertices = data->vertexCount_;
                        unsigned numIndices = data->indexCount_;
                        unsigned destVertexStart = build.vertices_.Size();
                        
                        for (unsigned j = 0; j < numVertices; ++j)
                            build.vertices_.Push(transform * data->vertexData_[j]);
                        
                        for (unsigned j = 0; j < numIndices; ++j)
                            build.indices_.Push(data->indexData_[j] + destVertexStart);
                    }
                    break;
                    
                case SHAPE_BOX:
                    {
                        unsigned destVertexStart = build.vertices_.Size();
                        
                        build.vertices_.Push(transform * Vector3(-0.5f, 0.5f, -0.5f));
                        build.vertices_.Push(transform * Vector3(0.5f, 0.5f, -0.5f));
                        build.vertices_.Push(transform * Vector3(0.5f, -0.5f, -0.5f));
                        build.vertices_.Push(transform * Vector3(-0.5f, -0.5f, -0.5f));
                        build.vertices_.Push(transform * Vector3(-0.5f, 0.5f, 0.5f));
                        build.vertices_.Push(transform * Vector3(0.5f, 0.5f, 0.5f));
                        build.vertices_.Push(transform * Vector3(0.5f, -0.5f, 0.5f));
                        build.vertices_.Push(transform * Vector3(-0.5f, -0.5f, 0.5f));
                        
                        const unsigned indices[] = {
                            0, 1, 2, 0, 2, 3, 1, 5, 6, 1, 6, 2, 4, 5, 1, 4, 1, 0, 5, 4, 7, 5, 7, 6,
                            4, 0, 3, 4, 3, 7, 1, 0, 4, 1, 4, 5
                        };
                        
                        for (unsigned j = 0; j < 36; ++j)
                            build.indices_.Push(indices[j] + destVertexStart);
                    }
                    break;
                        
                default:
                    break;
                }
                
                continue;
            }
            
            Drawable* drawable = dynamic_cast<Drawable*>(geometryList[i].component_);
            if (drawable)
            {
                const Vector<SourceBatch>& batches = drawable->GetBatches();
                
                for (unsigned j = 0; j < batches.Size(); ++j)
                    AddTriMeshGeometry(build, drawable->GetLodGeometry(j, geometryList[i].lodLevel_), transform);
            }
        }
    }
}
Ejemplo n.º 26
0
 /** Method to return an iterator pointing to the first item
  * in a given BoundingBox.
  */
 iterator begin(const BoundingBox& bb) const {
   assert(!bb.empty());
   return Iterator(this, bb, mc_.code(bb.min()), 0);
 }
Ejemplo n.º 27
0
 inline bool contains (const BoundingBox & b) const {
     for (unsigned int i = 0; i < 3; i++)
         if (fabs (getMiddle (i) - b.getMiddle (i)) - BOUNDINGBOX_EPSILON > (getWHL (i) + b.getWHL (i)) / 2.0)
             return false;
     return true;
 }
Ejemplo n.º 28
0
 /** Method to return an iterator pointing to "one past"
  * the last item in a given BoundingBox.
  */
 iterator end(const BoundingBox& bb) const {
   assert(!bb.empty());
   return Iterator(this, bb, mc_.code(bb.max())+1, 0);
 }
Ejemplo n.º 29
0
void Terrain::CreatePatchGeometry(TerrainPatch* patch)
{
    PROFILE(CreatePatchGeometry);

    unsigned row = patchSize_ + 1;
    VertexBuffer* vertexBuffer = patch->GetVertexBuffer();
    Geometry* geometry = patch->GetGeometry();
    Geometry* maxLodGeometry = patch->GetMaxLodGeometry();
    Geometry* minLodGeometry = patch->GetMinLodGeometry();

    if (vertexBuffer->GetVertexCount() != row * row)
        vertexBuffer->SetSize(row * row, MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1 | MASK_TANGENT);

    SharedArrayPtr<unsigned char> cpuVertexData(new unsigned char[row * row * sizeof(Vector3)]);

    float* vertexData = (float*)vertexBuffer->Lock(0, vertexBuffer->GetVertexCount());
    float* positionData = (float*)cpuVertexData.Get();
    BoundingBox box;

    if (vertexData)
    {
        const IntVector2& coords = patch->GetCoordinates();

        for (int z1 = 0; z1 <= patchSize_; ++z1)
        {
            for (int x1 = 0; x1 <= patchSize_; ++x1)
            {
                int xPos = coords.x_ * patchSize_ + x1;
                int zPos = coords.y_ * patchSize_ + z1;

                // Position
                Vector3 position((float)x1 * spacing_.x_, GetRawHeight(xPos, zPos), (float)z1 * spacing_.z_);
                *vertexData++ = position.x_;
                *vertexData++ = position.y_;
                *vertexData++ = position.z_;
                *positionData++ = position.x_;
                *positionData++ = position.y_;
                *positionData++ = position.z_;

                box.Merge(position);

                // Normal
                Vector3 normal = GetRawNormal(xPos, zPos);
                *vertexData++ = normal.x_;
                *vertexData++ = normal.y_;
                *vertexData++ = normal.z_;

                // Texture coordinate
                Vector2 texCoord((float)xPos / (float)numVertices_.x_, 1.0f - (float)zPos / (float)numVertices_.y_);
                *vertexData++ = texCoord.x_;
                *vertexData++ = texCoord.y_;

                // Tangent
                Vector3 xyz = (Vector3::RIGHT - normal * normal.DotProduct(Vector3::RIGHT)).Normalized();
                *vertexData++ = xyz.x_;
                *vertexData++ = xyz.y_;
                *vertexData++ = xyz.z_;
                *vertexData++ = 1.0f;
            }
        }

        vertexBuffer->Unlock();
        vertexBuffer->ClearDataLost();
    }

    patch->SetBoundingBox(box);

    if (drawRanges_.Size())
    {
        unsigned lastDrawRange = drawRanges_.Size() - 1;

        geometry->SetIndexBuffer(indexBuffer_);
        geometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[0].first_, drawRanges_[0].second_, false);
        geometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION);
        maxLodGeometry->SetIndexBuffer(indexBuffer_);
        maxLodGeometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[0].first_, drawRanges_[0].second_, false);
        maxLodGeometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION);
        minLodGeometry->SetIndexBuffer(indexBuffer_);
        minLodGeometry->SetDrawRange(TRIANGLE_LIST, drawRanges_[lastDrawRange].first_, drawRanges_[lastDrawRange].second_, false);
        minLodGeometry->SetRawVertexData(cpuVertexData, sizeof(Vector3), MASK_POSITION);
    }

    // Offset the occlusion geometry by vertex spacing to reduce possibility of over-aggressive occlusion
    patch->SetOcclusionOffset(-0.5f * (spacing_.x_ + spacing_.z_));
    patch->ResetLod();
}
ClusterVisualizer::ClusterVisualizer(string filename)
{
	ifstream in(filename.c_str());

	// Check!
	if(!in.good()) return;

	MeshCluster* cluster = new MeshCluster;

	// Read sub meshes
	while(in.good())
	{
		string cluster_name;
		int num_faces;
		int num_vertices;

		// Read 'header'
		in >> cluster_name;
		in >> num_faces >> num_vertices;
		BoundingBox<Vertex<float> > bb;
		// Alloc buffers
		if(num_faces && num_vertices)
		{


			floatArr vertices(new float[3 * num_vertices]);
			floatArr normals(new float[3 * num_vertices]);
			ucharArr colors(new uchar[3 * num_vertices]);
			uintArr indices(new uint[3 * num_faces]);

			// Read indices
			for(int i = 0; i < num_faces; i++)
			{
				int pos = 3 * i;
				uint a, b, c;
				in >> a >> b >> c;
				indices[pos    ] = a;
				indices[pos + 1] = b;
				indices[pos + 2] = c;
			}

			// Read vertices, normals and colors
			for(int i = 0; i < num_vertices; i++)
			{
				int pos = 3 * i;
				float x, y, z, nx, ny, nz;
				int r, g, b;

				in >> x >> y >> z >> nx >> ny >> nz >> r >> g >> b;

				vertices[pos    ] = x;
				vertices[pos + 1] = y;
				vertices[pos + 2] = z;

				normals[pos    ] = nx;
				normals[pos + 1] = ny;
				normals[pos + 2] = nz;

				colors[pos    ] = (uchar)r;
				colors[pos + 1] = (uchar)g;
				colors[pos + 2] = (uchar)b;

				bb.expand(x, y, z);
			}

			// Create Buffer
			MeshBufferPtr* buffer = new MeshBufferPtr(new MeshBuffer);
			buffer->get()->setVertexArray(vertices, num_vertices);
			buffer->get()->setVertexNormalArray(normals, num_vertices);
			buffer->get()->setVertexColorArray(colors, num_vertices);
			buffer->get()->setFaceArray(indices, num_faces);

			cluster->boundingBox()->expand(bb);
			cluster->addMesh(*buffer, cluster_name);

		}

	}