void WireframeSpheroid::bottomHemisphere(const Float endY, const UnsignedInt rings) {
    CORRADE_INTERNAL_ASSERT(_positions.empty());

    /* Initial vertex */
    _positions.push_back(Vector3::yAxis(endY - 1.0f));

    /* Connect initial vertex to first ring */
    for(UnsignedInt i = 0; i != 4; ++i)
        _indices.insert(_indices.end(), {0, i+1});

    /* Hemisphere vertices and indices */
    const Rad ringAngleIncrement(Constants::piHalf()/rings);
    for(UnsignedInt j = 0; j != rings-1; ++j) {
        const Rad angle = Float(j+1)*ringAngleIncrement;

        _positions.emplace_back(0.0f, endY - Math::cos(angle), Math::sin(angle));
        _positions.emplace_back(Math::sin(angle), endY - Math::cos(angle), 0.0f);
        _positions.emplace_back(0.0f, endY - Math::cos(angle), -Math::sin(angle));
        _positions.emplace_back(-Math::sin(angle), endY - Math::cos(angle), 0.0f);

        /* Connect vertices to next ring */
        for(UnsignedInt i = 0; i != 4; ++i)
            _indices.insert(_indices.end(), {UnsignedInt(_positions.size())-4+i, UnsignedInt(_positions.size())+i});
    }
}
void WireframeSpheroid::topHemisphere(const Float startY, const UnsignedInt rings) {
    /* Connect previous ring to following vertices */
    for(UnsignedInt i = 0; i != 4; ++i)
        _indices.insert(_indices.end(), {UnsignedInt(_positions.size())-4*_segments+i, UnsignedInt(_positions.size())+i});

    /* Hemisphere vertices and indices */
    const Rad ringAngleIncrement(Constants::piHalf()/rings);
    for(UnsignedInt j = 0; j != rings-1; ++j) {
        const Rad angle = Float(j+1)*ringAngleIncrement;

        /* Connect previous hemisphere ring to current vertices */
        if(j != 0) for(UnsignedInt i = 0; i != 4; ++i)
            _indices.insert(_indices.end(), {UnsignedInt(_positions.size())-4+i, UnsignedInt(_positions.size())+i});

        _positions.emplace_back(0.0f, startY + Math::sin(angle), Math::cos(angle));
        _positions.emplace_back(Math::cos(angle), startY + Math::sin(angle), 0.0f);
        _positions.emplace_back(0.0f, startY + Math::sin(angle), -Math::cos(angle));
        _positions.emplace_back(-Math::cos(angle), startY + Math::sin(angle), 0.0f);
    }

    /* Final vertex */
    _positions.push_back(Vector3::yAxis(startY + 1.0f));

    /* Connect last ring to final vertex */
    for(UnsignedInt i = 0; i != 4; ++i)
        _indices.insert(_indices.end(), {UnsignedInt(_positions.size())-5+i, UnsignedInt(_positions.size())-1});
}
Exemple #3
0
Trade::MeshData3D grid3DWireframe(const Vector2i& subdivisions) {
    const Vector2i vertexCount = subdivisions + Vector2i{2};
    const Vector2i faceCount = subdivisions + Vector2i{1};

    std::vector<Vector3> positions;
    positions.reserve(vertexCount.product());
    for(Int y = 0; y != vertexCount.y(); ++y)
        for(Int x = 0; x != vertexCount.x(); ++x)
            positions.emplace_back((Vector2(x, y)/Vector2(faceCount))*2.0f - Vector2{1.0f}, 0.0f);

    std::vector<UnsignedInt> indices;
    indices.reserve(vertexCount.y()*(vertexCount.x() - 1)*2 +
                    vertexCount.x()*(vertexCount.y() - 1)*2);
    for(Int y = 0; y != vertexCount.y(); ++y) {
        for(Int x = 0; x != vertexCount.x(); ++x) {
            /* 3    7
               |    | ...
               2    6
               0--1 4--5 ... */
            if(x != vertexCount.x() - 1) indices.insert(indices.end(), {
                UnsignedInt(y*vertexCount.x() + x),
                UnsignedInt(y*vertexCount.x() + x + 1)});
            if(y != vertexCount.y() - 1) indices.insert(indices.end(), {
                UnsignedInt(y*vertexCount.x() + x),
                UnsignedInt((y + 1)*vertexCount.x() + x)});
        }
    }

    return Trade::MeshData3D{MeshPrimitive::Lines, std::move(indices), {std::move(positions)}, {}, {}, {}, nullptr};
}
Exemple #4
0
Trade::MeshData2D Capsule2D::wireframe(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, Float halfLength) {
    CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", Trade::MeshData2D(MeshPrimitive::Lines, std::vector<UnsignedInt>{}, std::vector<std::vector<Vector2>>{}, std::vector<std::vector<Vector2>>{}));

    std::vector<Vector2> positions;
    positions.reserve(hemisphereRings*4+2+(cylinderRings-1)*2);
    const Rad angleIncrement(Constants::pi()/(2.0f*hemisphereRings));
    const Float cylinderIncrement = 2.0f*halfLength/cylinderRings;

    /* Bottom cap vertex */
    positions.emplace_back(0.0f, -halfLength-1.0f);

    /* Bottom hemisphere */
    for(UnsignedInt i = 0; i != hemisphereRings; ++i) {
        const Rad angle(Float(i+1)*angleIncrement);
        const Float x = Math::sin(angle);
        const Float y = -Math::cos(angle)-halfLength;
        positions.insert(positions.end(), {{-x, y}, {x, y}});
    }

    /* Cylinder (bottom and top vertices are done within caps */
    for(UnsignedInt i = 0; i != cylinderRings-1; ++i) {
        const Float y = (i+1)*cylinderIncrement-halfLength;
        positions.insert(positions.end(), {{-1.0f, y}, {1.0f, y}});
    }

    /* Top hemisphere */
    for(UnsignedInt i = 0; i != hemisphereRings; ++i) {
        const Rad angle(Float(i)*angleIncrement);
        const Float x = Math::cos(angle);
        const Float y = Math::sin(angle)+halfLength;
        positions.insert(positions.end(), {{-x, y}, {x, y}});
    }

    /* Top cap vertex */
    positions.emplace_back(0.0f, halfLength+1.0f);

    std::vector<UnsignedInt> indices;
    indices.reserve(hemisphereRings*8+cylinderRings*4);

    /* Bottom cap indices */
    indices.insert(indices.end(), {0, 1, 0, 2});

    /* Side indices */
    for(UnsignedInt i = 0; i != cylinderRings+hemisphereRings*2-2; ++i)
        indices.insert(indices.end(), {i*2+1, i*2+3,
                                       i*2+2, i*2+4});

    /* Top cap indices */
    indices.insert(indices.end(),
        {UnsignedInt(positions.size())-3, UnsignedInt(positions.size())-1,
         UnsignedInt(positions.size())-2, UnsignedInt(positions.size())-1});

    return Trade::MeshData2D(MeshPrimitive::Lines, std::move(indices), {std::move(positions)}, std::vector<std::vector<Vector2>>{});
}
void WireframeSpheroid::ring(const Float y) {
    /* Ring vertices and indices */
    const Rad segmentAngleIncrement(Constants::piHalf()/_segments);
    for(UnsignedInt j = 0; j != _segments; ++j) {
        for(UnsignedInt i = 0; i != 4; ++i) {
            const Rad segmentAngle = Rad(Float(i)*Constants::piHalf()) + Float(j)*segmentAngleIncrement;
            if(j != 0) _indices.insert(_indices.end(), {UnsignedInt(_positions.size()-4), UnsignedInt(_positions.size())});
            _positions.emplace_back(Math::sin(segmentAngle), y, Math::cos(segmentAngle));
        }
    }

    /* Close the ring */
    for(UnsignedInt i = 0; i != 4; ++i)
        _indices.insert(_indices.end(), {UnsignedInt(_positions.size())-4+i, UnsignedInt(_positions.size())-4*_segments+(i+1)%4});
}
Exemple #6
0
void Timeline::nextFrame() {
    if(!running) return;

    auto now = high_resolution_clock::now();
    auto duration = UnsignedInt(duration_cast<microseconds>(now-_previousFrameTime).count());
    _previousFrameDuration = duration/1e6f;
    _previousFrameTime = now;
}
Exemple #7
0
void Timeline::nextFrame() {
    if(!running) return;

    auto now = high_resolution_clock::now();
    auto duration = UnsignedInt(duration_cast<microseconds>(now-_previousFrameTime).count());
    _previousFrameDuration = duration/1e6f;

    if(_previousFrameDuration < _minimalFrameTime) {
        Utility::sleep(std::size_t(_minimalFrameTime*1000) - duration/1000);
        now = high_resolution_clock::now();
        _previousFrameDuration = duration_cast<microseconds>(now-_previousFrameTime).count()/1e6f;
    }

    _previousFrameTime = now;
}
Exemple #8
0
Trade::MeshData3D grid3DSolid(const Vector2i& subdivisions, const GridFlags flags) {
    const Vector2i vertexCount = subdivisions + Vector2i{2};
    const Vector2i faceCount = subdivisions + Vector2i{1};

    std::vector<Vector3> positions;
    positions.reserve(vertexCount.product());
    for(Int y = 0; y != vertexCount.y(); ++y)
        for(Int x = 0; x != vertexCount.x(); ++x)
            positions.emplace_back((Vector2(x, y)/Vector2(faceCount))*2.0f - Vector2{1.0f}, 0.0f);

    std::vector<UnsignedInt> indices;
    indices.reserve(faceCount.product()*6);
    for(Int y = 0; y != faceCount.y(); ++y) {
        for(Int x = 0; x != faceCount.x(); ++x) {
            /* 2--1 5
               | / /|
               |/ / |
               0 3--4 */
            indices.insert(indices.end(), {
                UnsignedInt(y*vertexCount.x() + x),
                UnsignedInt((y + 1)*vertexCount.x() + x + 1),
                UnsignedInt((y + 1)*vertexCount.x() + x + 0),
                UnsignedInt(y*vertexCount.x() + x),
                UnsignedInt(y*vertexCount.x() + x + 1),
                UnsignedInt((y + 1)*vertexCount.x() + x + 1)});
        }
    }

    std::vector<std::vector<Vector3>> normals;
    if(flags & GridFlag::GenerateNormals)
        normals.emplace_back(positions.size(), Vector3::zAxis(1.0f));

    std::vector<std::vector<Vector2>> textureCoordinates;
    if(flags & GridFlag::GenerateTextureCoords) {
        textureCoordinates.emplace_back();
        textureCoordinates[0].reserve(positions.size());
        for(std::size_t i = 0; i != positions.size(); ++i)
            textureCoordinates[0].emplace_back(positions[i].xy()*0.5f + Vector2{0.5f});
    }

    return Trade::MeshData3D{MeshPrimitive::Triangles, std::move(indices), {std::move(positions)}, std::move(normals), std::move(textureCoordinates), {}, nullptr};
}
void WireframeSpheroid::cylinder() {
    /* Connect four vertex pairs of previous and next ring */
    for(UnsignedInt i = 0; i != 4; ++i)
        _indices.insert(_indices.end(), {UnsignedInt(_positions.size())-4*_segments+i, UnsignedInt(_positions.size())+i});
}
// CHECK-LABEL: @explicit_functional_unsigned_int_to_unsigned_int
unsigned int explicit_functional_unsigned_int_to_unsigned_int(unsigned int src) {
  // CHECK-SANITIZE-NOT: call
  // CHECK: }
  return UnsignedInt(src);
}