【开发日志】2023.03.04 ZENO----SimpleGeometry----CreateSphere

这段代码定义了一个名为CreateSphere的ZenONode,用于创建球体几何体。它接受位置、缩放、半径、行列数等参数,生成网格并处理纹理坐标和法线。代码中还包括了处理四边形和三角形的转换,以及根据输入参数调整几何体的细节。
摘要由CSDN通过智能技术生成

 

struct CreateSphere : zeno::INode {
    virtual void apply() override {
        auto prim = std::make_shared<zeno::PrimitiveObject>();
        auto position = get_input2<zeno::vec3f>("position");
        auto scale = get_input2<zeno::vec3f>("scaleSize");
        auto rows = get_input2<int>("rows");
        auto columns = get_input2<int>("columns");
        auto radius = get_input2<float>("radius");
        auto quad = get_input2<bool>("quads");

        if (rows < 2) {
            rows = 2;
        }
        if (columns < 3) {
            columns = 3;
        }
        std::vector<zeno::vec3f> verts = {};
        std::vector<zeno::vec2i> poly = {};
        std::vector<int> loops = {};
        std::vector<zeno::vec2f> uvs = {};
        std::vector<zeno::vec3f> nors = {};

        verts.push_back (vec3f(0,1,0));
        for (auto row = 1; row < rows; row++) {
            float v = (float)row / (float)rows;
            float theta = M_PI * v;
            for (auto column = 0; column < columns; column++) {
                float u = (float)column / (float)columns;
                float phi = M_PI * 2 * u;
                float x = sin(theta) * cos(phi);
                float y = cos(theta);
                float z = -sin(theta) * sin(phi);
                verts.push_back(vec3f(x,y,z));
            }
        }
        verts.push_back (vec3f(0,-1,0));
        {
            //head
            for (auto column = 0; column < columns; column++) {
                if (column == columns - 1) {
                    loops.push_back(0);
                    loops.push_back(columns);
                    loops.push_back(1);
                    poly.push_back(vec2i(column * 3, 3));
                } else {
                    loops.push_back(0);
                    loops.push_back(column + 1);
                    loops.push_back(column + 2);
                    poly.push_back(vec2i(column * 3, 3));
                }
            }
            //body
            for (auto row = 1; row < rows - 1; row++) {
                for (auto column = 0; column < columns; column++) {
                    if (column == columns - 1) {
                        loops.push_back((row - 1) * columns + 1);
                        loops.push_back((row - 1) * columns + columns);
                        loops.push_back(row * columns + columns);
                        loops.push_back(row * columns + 1);
                        poly.push_back(vec2i(columns * 3 + (row - 1) * columns * 4 + column * 4, 4));
                    } else {
                        loops.push_back((row - 1) * columns + column + 2);
                        loops.push_back((row - 1) * columns + column + 1);
                        loops.push_back(row * columns + column + 1);
                        loops.push_back(row * columns + column + 2);
                        poly.push_back(vec2i(loops.size() - 4, 4));
                    }
                }
            }
            //tail
            for (auto column = 0; column < columns; column++) {
                if (column == columns - 1) {
                    loops.push_back((rows - 2) * columns + 1);
                    loops.push_back((rows - 2) * columns + column + 1);
                    loops.push_back((rows - 1) * columns + 1);
                    poly.push_back(vec2i(columns * 3 + (rows - 2) * columns * 4 + column * 3, 3));
                } else {
                    loops.push_back((rows - 2) * columns + column + 2);
                    loops.push_back((rows - 2) * columns + column + 1);
                    loops.push_back((rows - 1) * columns + 1);
                    poly.push_back(vec2i(loops.size() - 3, 3));
                }
            }
        }

        for(int column = 0;column < columns;column++){
            uvs.push_back({(column+0.5f)/columns, 1.0f, 0.0f});
        }
        for(int row = 1;row < rows;row++){
            for(int column = 0;column < columns+1;column++){
                uvs.push_back({(column+0.0f)/columns,1.0f-(row+0.0f)/rows,0.0f});
            }
        }
        for(int column = 0;column < columns;column++){
            uvs.push_back({(column+0.5f)/columns, 0.0f, 0.0f});
        }

        auto& loops_uv = prim->loops.add_attr<int>("uvs");
        loops_uv.resize(0);
        for(int column = 0;column < columns;column++){
            loops_uv.push_back(column);
            loops_uv.push_back(columns+column);
            loops_uv.push_back(columns+column+1);
        }
        for(int row = 1;row < rows-1;row++){
            for(int column = 0;column < columns;column++){
                loops_uv.push_back(columns+(columns+1)*(row-1)+column+1);
                loops_uv.push_back(columns+(columns+1)*(row-1)+column);
                loops_uv.push_back(columns+(columns+1)*row+column);
                loops_uv.push_back(columns+(columns+1)*row+column+1);
            }
        }
        for(int column = 0;column < columns;column++){
            loops_uv.push_back(columns+(columns+1)*(rows-2)+column+1);
            loops_uv.push_back(columns+(columns+1)*(rows-2)+column);
            loops_uv.push_back(columns+(columns+1)*(rows-1)+column);
        }

        nors.resize(verts.size());
        for(int i = 0; i < verts.size(); i++){
            auto n = verts[i];
            auto p = verts[i];
            auto rotate = get_input2<zeno::vec3f>("rotate");
            glm::mat4 transform = glm::mat4 (1.0);
            transform = glm::translate(transform, glm::vec3(position[0], position[1], position[2]));
            transform = glm::rotate(transform, glm::radians(rotate[0]), glm::vec3(1, 0, 0));
            transform = glm::rotate(transform, glm::radians(rotate[1]), glm::vec3(0, 1, 0));
            transform = glm::rotate(transform, glm::radians(rotate[2]), glm::vec3(0, 0, 1));
            transform = glm::scale(transform, glm::vec3(scale[0],scale[1],scale[2]) * radius);
            auto gp = transform * glm::vec4(p[0], p[1], p[2], 1);
            verts[i] = zeno::vec3f(gp.x, gp.y, gp.z);

            auto n_transform = glm::transpose(glm::inverse(transform));
            auto gn = n_transform * glm::vec4 (n[0], n[1], n[2], 0);
            nors[i] = zeno::vec3f (gn.x, gn.y, gn.z);
        }

        prim->verts.resize(verts.size());
        for (auto i = 0; i < verts.size(); i++) {
            prim->verts[i] = verts[i];
        }
        prim->polys.resize(poly.size());
        for (auto i = 0; i < poly.size(); i++) {
            prim->polys[i] = poly[i];
        }
        prim->loops.resize(loops.size());
        for (auto i = 0; i < loops.size(); i++) {
            prim->loops[i] = loops[i];
        }
        prim->uvs.resize(uvs.size());

        for (auto i = 0; i < uvs.size(); i++) {
            prim->uvs[i] = uvs[i];
        }

        auto &nors2 = prim->verts.add_attr<zeno::vec3f>("nrm");
        for (auto i = 0; i < nors.size(); i++) {
            nors2[i] = nors[i];
        }

        if (!get_input2<bool>("hasNormal")){
            prim->verts.attrs.erase("nrm");
        }

        if (!get_input2<bool>("hasVertUV")){
            prim->uvs.clear();
            prim->loops.erase_attr("uvs");
        }

        if (get_input2<bool>("isFlipFace")){
            for (auto i = 0; i < prim->polys.size(); i++) {
                auto [base, cnt] = prim->polys[i];
                for (int j = 0; j < (cnt / 2); j++) {
                    std::swap(prim->loops[base + j], prim->loops[base + cnt - 1 - j]);
                    if (prim->loops.has_attr("uvs")) {
                        std::swap(prim->loops.attr<int>("uvs")[base + j], prim->loops.attr<int>("uvs")[base + cnt - 1 - j]);
                    }
                }
            }
        }

        if(!quad){
            primTriangulate(prim.get());
        }
        set_output("prim",std::move(prim));
    }
};

ZENDEFNODE(CreateSphere, {
    {
        {"vec3f", "position", "0, 0, 0"},
        {"vec3f", "scaleSize", "1, 1, 1"},
        {"float", "radius", "1"},
        ROTATE_PARM
        NORMUV_PARM
        {"int", "rows", "12"},
        {"int", "columns", "24"},
        {"bool", "quads", "0"},
    },
    {"prim"},
    {},
    {"create"},
});


Deprecated

struct CreateSphere : zeno::INode {
    virtual void apply() override {
        auto prim = std::make_shared<zeno::PrimitiveObject>();
        auto position = get_input2<zeno::vec3f>("position");
        auto scale = get_input2<zeno::vec3f>("scaleSize");
        auto rows = get_input2<int>("rows");
        auto columns = get_input2<int>("columns");
        auto radius = get_input2<float>("radius");
        auto quad = get_input2<bool>("quads");

        if (rows < 2) {
            rows = 2;
        }
        if (columns < 3) {
            columns = 3;
        }

        auto &uvs = prim->verts.add_attr<zeno::vec3f>("uv");
        auto &nors = prim->verts.add_attr<zeno::vec3f>("nrm");
        auto &verts = prim->verts;
        auto &tris = prim->tris;
        auto &uv0 = prim->tris.add_attr<zeno::vec3f>("uv0");
        auto &uv1 = prim->tris.add_attr<zeno::vec3f>("uv1");
        auto &uv2 = prim->tris.add_attr<zeno::vec3f>("uv2");
        auto &poly = prim->polys;
        auto &loops = prim->loops;

        verts.push_back (vec3f(0,1,0));
        for (auto row = 1; row < rows; row++) {
            float v = (float)row / (float)rows;
            float theta = M_PI * v;
            for (auto column = 0; column < columns; column++) {
                float u = (float)column / (float)columns;
                float phi = M_PI * 2 * u;
                float x = sin(theta) * cos(phi);
                float y = cos(theta) ;
                float z = -sin(theta) * sin(phi);

                verts.push_back(vec3f(x,y,z));
            }
        }
        verts.push_back (vec3f(0,-1,0));

        {
            //head
            for (auto column = 0; column < columns; column++) {
                // auto quad_index = column;
                if (column == columns - 1) {
                    loops->push_back(0);
                    loops->push_back(columns);
                    loops->push_back(1);
                    poly->push_back(vec2i(column * 3, 3));
                } else {
                    loops->push_back(0);
                    loops->push_back(column + 1);
                    loops->push_back(column + 2);
                    poly->push_back(vec2i(column * 3, 3));
                }
            }
            //body
            for (auto row = 1; row < rows - 1; row++) {
                for (auto column = 0; column < columns; column++) {
                    if (column == columns - 1) {
                        loops->push_back((row - 1) * columns + 1);
                        loops->push_back((row - 1) * columns + columns);
                        loops->push_back(row * columns + columns);
                        loops->push_back(row * columns + 1);
                        poly->push_back(vec2i(columns * 3 + (row - 1) * columns * 4 + column * 4, 4));
                    } else {
                        loops->push_back((row - 1) * columns + column + 2);
                        loops->push_back((row - 1) * columns + column + 1);
                        loops->push_back(row * columns + column + 1);
                        loops->push_back(row * columns + column + 2);
                        poly->push_back(vec2i(loops->size() - 4, 4));
                    }
                }
            }
            //tail
            for (auto column = 0; column < columns; column++) {
                // auto quad_index = column;
                if (column == columns - 1) {
                    loops->push_back((rows - 2) * columns + 1);
                    loops->push_back((rows - 2) * columns + column + 1);
                    loops->push_back((rows - 1) * columns + 1);
                    poly->push_back(vec2i(columns * 3 + (rows - 2) * columns * 4 + column * 3, 3));
                } else {
                    loops->push_back((rows - 2) * columns + column + 2);
                    loops->push_back((rows - 2) * columns + column + 1);
                    loops->push_back((rows - 1) * columns + 1);
                    poly->push_back(vec2i(loops->size() - 3, 3));
                }
            }
        }

        for(int column = 0;column < columns;column++){
            prim->uvs.push_back({(column+0.5f)/columns, 1.0f, 0.0f});
        }
        for(int row = 1;row < rows;row++){
            for(int column = 0;column < columns+1;column++){
                prim->uvs.push_back({(column+0.0f)/columns,1.0f-(row+0.0f)/rows,0.0f});
            }
        }
        for(int column = 0;column < columns;column++){
            prim->uvs.push_back({(column+0.5f)/columns, 0.0f, 0.0f});
        }

        auto& loops_uv = prim->loops.add_attr<int>("uvs");
        loops_uv.resize(0);
        for(int column = 0;column < columns;column++){
            loops_uv.push_back(column);
            loops_uv.push_back(columns+column);
            loops_uv.push_back(columns+column+1);
        }
        for(int row = 1;row < rows-1;row++){
            for(int column = 0;column < columns;column++){
                loops_uv.push_back(columns+(columns+1)*(row-1)+column+1);
                loops_uv.push_back(columns+(columns+1)*(row-1)+column);
                loops_uv.push_back(columns+(columns+1)*row+column);
                loops_uv.push_back(columns+(columns+1)*row+column+1);
            }
        }
        for(int column = 0;column < columns;column++){
            loops_uv.push_back(columns+(columns+1)*(rows-2)+column+1);
            loops_uv.push_back(columns+(columns+1)*(rows-2)+column);
            loops_uv.push_back(columns+(columns+1)*(rows-1)+column);
        }

        nors.resize(prim->verts.size());
        for(int i = 0;i < verts.size();i++){
            auto n = verts[i];

            auto p = verts[i];
            auto rotate = get_input2<zeno::vec3f>("rotate");
            glm::mat4 transform = glm::mat4 (1.0);
            transform = glm::translate(transform, glm::vec3(position[0], position[1], position[2]));
            transform = glm::rotate(transform, glm::radians(rotate[0]), glm::vec3(1, 0, 0));
            transform = glm::rotate(transform, glm::radians(rotate[1]), glm::vec3(0, 1, 0));
            transform = glm::rotate(transform, glm::radians(rotate[2]), glm::vec3(0, 0, 1));
            transform = glm::scale(transform, glm::vec3(scale[0],scale[1],scale[2]) * radius);
            auto gp = transform * glm::vec4(p[0], p[1], p[2], 1);
            verts[i] = zeno::vec3f(gp.x, gp.y, gp.z);

            auto n_transform = glm::transpose(glm::inverse(transform));
            auto gn = n_transform * glm::vec4 (n[0], n[1], n[2], 0);
            nors[i] = zeno::vec3f (gn.x, gn.y, gn.z);
        }
        if(!quad){
            primTriangulate(prim.get());
        }
        set_output("prim",std::move(prim));
    }
};

ZENDEFNODE(CreateSphere, {
    {
        {"vec3f", "position", "0, 0, 0"},
        {"vec3f", "scaleSize", "1, 1, 1"},
        {"float", "radius", "1"},
        ROTATE_PARM
        NORMUV_PARM
        {"int", "rows", "12"},
        {"int", "columns", "24"},
        {"bool", "quads", "0"},
    },
    {"prim"},
    {},
    {"create"},
});

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值