diff --git a/projects/FBX/MayaCamera.cpp b/projects/FBX/MayaCamera.cpp index 8910fc3711..b7bc1bb428 100644 --- a/projects/FBX/MayaCamera.cpp +++ b/projects/FBX/MayaCamera.cpp @@ -256,7 +256,15 @@ struct LightNode : INode { auto exposure = get_input2("exposure"); auto intensity = get_input2("intensity"); - intensity *= pow(2.0, exposure); + + auto scaler = powf(2.0f, exposure); + + if (std::isnan(scaler) || std::isinf(scaler) || scaler < 0.0f) { + scaler = 1.0f; + printf("Light exposure = %f is invalid, fallback to 0.0 \n", exposure); + } + + intensity *= scaler; auto prim = std::make_shared(); auto &verts = prim->verts; @@ -301,6 +309,14 @@ struct LightNode : INode { auto &clr = prim->verts.add_attr("clr"); auto c = color * intensity; + + for (size_t i=0; i Status Bar 状态栏 + + + File Saved + 文件已保存 + + + File Opened + 文件已打开 layout format is invalid. diff --git a/ui/zenoedit/viewport/cameracontrol.cpp b/ui/zenoedit/viewport/cameracontrol.cpp index f2b8fe156c..f9427ed9d5 100644 --- a/ui/zenoedit/viewport/cameracontrol.cpp +++ b/ui/zenoedit/viewport/cameracontrol.cpp @@ -103,6 +103,9 @@ void CameraControl::fakeMousePressEvent(QMouseEvent *event) { ZASSERT_EXIT(m_zenovis); auto scene = m_zenovis->getSession()->get_scene(); + if (event->button() == Qt::MiddleButton) { + middle_button_pressed = true; + } if (scene->camera->m_need_sync) { scene->camera->m_need_sync = false; if (bool(m_picker) && scene->camera->m_auto_radius) { @@ -369,8 +372,8 @@ void CameraControl::fakeWheelEvent(QWheelEvent *event) { ZenoSettingsManager& settings = ZenoSettingsManager::GetInstance(); int scaleKey = settings.getViewShortCut(ShortCut_ScalingView, button); if (shift_pressed) { - float temp = getFOV() / scale; - setFOV(temp < 170 ? temp : 170); +// float temp = getFOV() / scale; +// setFOV(temp < 170 ? temp : 170); } else if (aperture_pressed) { float temp = getAperture() + delta * 0.01; @@ -480,6 +483,9 @@ QVariant CameraControl::hitOnFloor(float x, float y) const { } void CameraControl::fakeMouseReleaseEvent(QMouseEvent *event) { + if (event->button() == Qt::MiddleButton) { + middle_button_pressed = false; + } if (event->button() == Qt::LeftButton) { //if (Zenovis::GetInstance().m_bAddPoint == true) { @@ -630,6 +636,54 @@ void CameraControl::fakeMouseReleaseEvent(QMouseEvent *event) { } } +bool CameraControl::fakeKeyPressEvent(int uKey) { + if (!middle_button_pressed) { + return false; + } + float cos_t = cos(getTheta()); + float sin_t = sin(getTheta()); + float cos_p = cos(getPhi()); + float sin_p = sin(getPhi()); + zeno::vec3f back(cos_t * sin_p, sin_t, -cos_t * cos_p); + zeno::vec3f up(-sin_t * sin_p, cos_t, sin_t * cos_p); + zeno::vec3f left = zeno::cross(up, back); + auto center = getCenter(); + float step = 1.0f; + + bool processed = false; + if (uKey == Qt::Key_Q) { + setCenter(center + zeno::vec3f(0, -1, 0) * step); + processed = true; + } + else if (uKey == Qt::Key_E) { + setCenter(center + zeno::vec3f(0, 1, 0) * step); + processed = true; + } + else if (uKey == Qt::Key_W) { + setCenter(center + back * step); + processed = true; + } + else if (uKey == Qt::Key_S) { + setCenter(center - back * step); + processed = true; + } + else if (uKey == Qt::Key_A) { + setCenter(center + left * step); + processed = true; + } + else if (uKey == Qt::Key_D) { + setCenter(center - left * step); + processed = true; + } + if (processed) { + updatePerspective(); + return true; + } + else { + return false; + } +} + //void CameraControl::createPointNode(QPointF pnt) { //auto pModel = zenoApp->graphsManagment()->currentModel(); //ZASSERT_EXIT(pModel); diff --git a/ui/zenoedit/viewport/cameracontrol.h b/ui/zenoedit/viewport/cameracontrol.h index 64a5ecd726..db3f10b544 100644 --- a/ui/zenoedit/viewport/cameracontrol.h +++ b/ui/zenoedit/viewport/cameracontrol.h @@ -38,6 +38,7 @@ class CameraControl : public QObject void updatePerspective(); void setKeyFrame(); + bool fakeKeyPressEvent(int uKey); void fakeMousePressEvent(QMouseEvent* event); void fakeMouseReleaseEvent(QMouseEvent* event); void fakeMouseMoveEvent(QMouseEvent* event); @@ -63,6 +64,8 @@ class CameraControl : public QObject std::shared_ptr m_picker; std::shared_ptr m_transformer; Zenovis* m_zenovis; + + bool middle_button_pressed = false; }; diff --git a/ui/zenoedit/viewport/viewportwidget.cpp b/ui/zenoedit/viewport/viewportwidget.cpp index 388c6f3c3c..3aa0670736 100644 --- a/ui/zenoedit/viewport/viewportwidget.cpp +++ b/ui/zenoedit/viewport/viewportwidget.cpp @@ -342,6 +342,12 @@ void ViewportWidget::keyPressEvent(QKeyEvent *event) if (modifiers & Qt::AltModifier) { uKey += Qt::ALT; } + + if (m_camera->fakeKeyPressEvent(uKey)) { + zenoApp->getMainWindow()->updateViewport(); + return; + } + if (uKey == key) this->changeTransformOperation(0); key = settings.getShortCut(ShortCut_RevolvingHandler); diff --git a/ui/zenoedit/zenomainwindow.cpp b/ui/zenoedit/zenomainwindow.cpp index 4b03ef5bfa..06cc110fad 100644 --- a/ui/zenoedit/zenomainwindow.cpp +++ b/ui/zenoedit/zenomainwindow.cpp @@ -1635,6 +1635,9 @@ bool ZenoMainWindow::openFile(QString filePath) recordRecentFile(filePath); initUserdata(pGraphs->userdataInfo()); //resetDocks(pGraphs->layoutInfo().layerOutNode); + + m_ui->statusbar->showMessage(tr("File Opened")); + zeno::scope_exit sp([&]() {QTimer::singleShot(2000, this, [=]() {m_ui->statusbar->showMessage(tr("Status Bar")); }); }); return true; } @@ -1978,6 +1981,9 @@ bool ZenoMainWindow::saveFile(QString filePath) settings.userdataInfo.optix_show_background = ud.get2("optix_show_background", false); zenoApp->graphsManagment()->saveFile(filePath, settings); recordRecentFile(filePath); + + m_ui->statusbar->showMessage(tr("File Saved")); + zeno::scope_exit sp([&]() {QTimer::singleShot(2000, this, [=]() {m_ui->statusbar->showMessage(tr("Status Bar")); }); }); return true; } diff --git a/zeno/src/nodes/prim/PrimitiveHeatmap.cpp b/zeno/src/nodes/prim/PrimitiveHeatmap.cpp index e46240ccfb..c1ce22c5ee 100644 --- a/zeno/src/nodes/prim/PrimitiveHeatmap.cpp +++ b/zeno/src/nodes/prim/PrimitiveHeatmap.cpp @@ -93,6 +93,54 @@ ZENDEFNODE(HeatmapFromImage, "visualize", }}); +struct HeatmapFromImage2 : zeno::INode { + virtual void apply() override { + auto image = get_input("image"); + int w = image->userData().get2("w"); + auto heatmap = std::make_shared(); + + auto spos = get_input2("startPos"); + auto epos = get_input2("endPos"); + int start = zeno::clamp(spos, 0.0f, 1.0f) * w; + int end = zeno::clamp(epos, 0.0f, 1.0f) * w; + std::vector temp; + for (auto i = start; i < end; i++) { + temp.push_back(image->verts[i]); + } + + auto resample = get_input2("resample"); + if (0 < resample && resample < w) { + for (auto i = 0; i < resample; i++) { + float x = i / float(resample); + x = zeno::clamp(x, 0, 1) * temp.size(); + int j = (int) zeno::floor(x); + j = zeno::clamp(j, 0, temp.size() - 2); + float f = x - j; + auto c = (1 - f) * temp.at(j) + f * temp.at(j + 1); + heatmap->colors.push_back(c); + } + } + else { + heatmap->colors = temp; + } + + set_output("heatmap", std::move(heatmap)); + } +}; + +ZENDEFNODE(HeatmapFromImage2, + { /* inputs: */ { + "image", + {"float", "startPos", "0"}, + {"float", "endPos", "1"}, + {"int", "resample", "0"}, + }, /* outputs: */ { + "heatmap", + }, /* params: */ { + }, /* category: */ { + "visualize", + }}); + struct PrimitiveColorByHeatmap : zeno::INode { virtual void apply() override { auto prim = get_input("prim"); diff --git a/zenovis/src/bate/GraphicPrimitive.cpp b/zenovis/src/bate/GraphicPrimitive.cpp index df73a75548..39098b4f06 100644 --- a/zenovis/src/bate/GraphicPrimitive.cpp +++ b/zenovis/src/bate/GraphicPrimitive.cpp @@ -354,12 +354,50 @@ struct ZhxxGraphicPrimitive final : IGraphicDraw { std::shared_ptr primUnique; zeno::PrimitiveObject *prim; + ZhxxDrawObject polyEdgeObj = {}; + explicit ZhxxGraphicPrimitive(Scene *scene_, zeno::PrimitiveObject *primArg) : scene(scene_), primUnique(std::make_shared(*primArg)) { prim = primUnique.get(); invisible = prim->userData().get2("invisible", 0); zeno::log_trace("rendering primitive size {}", prim->size()); + { + bool any_not_triangle = false; + for (const auto &[b, c]: prim->polys) { + if (c > 3) { + any_not_triangle = true; + } + } + if (any_not_triangle) { + std::vector edge_list; + auto add_edge = [&](int a, int b) { + int p0 = prim->loops[a]; + int p1 = prim->loops[b]; + edge_list.push_back(p0); + edge_list.push_back(p1); + }; + for (const auto &[b, c]: prim->polys) { + for (auto i = 2; i < c; i++) { + if (i == 2) { + add_edge(b, b + 1); + } + add_edge(b + i - 1, b + i); + if (i == c - 1) { + add_edge(b, b + i); + } + } + } + polyEdgeObj.count = edge_list.size(); + polyEdgeObj.ebo = std::make_unique(GL_ELEMENT_ARRAY_BUFFER); + polyEdgeObj.ebo->bind_data(edge_list.data(), edge_list.size() * sizeof(edge_list[0])); + auto vbo = std::make_unique(GL_ARRAY_BUFFER); + vbo->bind_data(prim->verts.data(), prim->verts.size() * sizeof(prim->verts[0])); + polyEdgeObj.vbos.push_back(std::move(vbo)); + polyEdgeObj.prog = get_edge_program(); + } + } + if (!prim->attr_is("pos")) { auto &pos = prim->add_attr("pos"); for (size_t i = 0; i < pos.size(); i++) { @@ -643,15 +681,34 @@ struct ZhxxGraphicPrimitive final : IGraphicDraw { bool selected = scene->selected.count(nameid) > 0; if (scene->drawOptions->render_wireframe || selected) { - CHECK_GL(glEnable(GL_POLYGON_OFFSET_LINE)); - CHECK_GL(glPolygonOffset(0, 0)); - CHECK_GL(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); - triObj.prog->set_uniformi("mRenderWireframe", true); - CHECK_GL(glDrawElements(GL_TRIANGLES, - /*count=*/triObj.count * 3, - GL_UNSIGNED_INT, /*first=*/0)); - CHECK_GL(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); - CHECK_GL(glDisable(GL_POLYGON_OFFSET_LINE)); + if (polyEdgeObj.count) { + polyEdgeObj.prog->use(); + scene->camera->set_program_uniforms(polyEdgeObj.prog); + + polyEdgeObj.vbos[0]->bind(); + polyEdgeObj.vbos[0]->attribute(/*index=*/0, + /*offset=*/sizeof(float) * 0, + /*stride=*/sizeof(float) * 3, GL_FLOAT, + /*count=*/3); + polyEdgeObj.ebo->bind(); + + CHECK_GL(glDrawElements(GL_LINES, polyEdgeObj.count, GL_UNSIGNED_INT, 0)); + + polyEdgeObj.ebo->unbind(); + polyEdgeObj.vbos[0]->disable_attribute(0); + polyEdgeObj.vbos[0]->unbind(); + } + else { + CHECK_GL(glEnable(GL_POLYGON_OFFSET_LINE)); + CHECK_GL(glPolygonOffset(0, 0)); + CHECK_GL(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); + triObj.prog->set_uniformi("mRenderWireframe", true); + CHECK_GL(glDrawElements(GL_TRIANGLES, + /*count=*/triObj.count * 3, + GL_UNSIGNED_INT, /*first=*/0)); + CHECK_GL(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); + CHECK_GL(glDisable(GL_POLYGON_OFFSET_LINE)); + } } triObj.ebo->unbind(); if (triObj.vbos.size()) { @@ -695,6 +752,17 @@ struct ZhxxGraphicPrimitive final : IGraphicDraw { return scene->shaderMan->compile_program(vert, frag); } + + Program *get_edge_program() { + auto vert = +#include "shader/edge.vert" + ; + + auto frag = +#include "shader/edge.frag" + ; + return scene->shaderMan->compile_program(vert, frag); + } }; } diff --git a/zenovis/src/bate/shader/edge.frag b/zenovis/src/bate/shader/edge.frag new file mode 100644 index 0000000000..ecd20cf189 --- /dev/null +++ b/zenovis/src/bate/shader/edge.frag @@ -0,0 +1,16 @@ +R"(#version 130 + +uniform mat4 mVP; +uniform mat4 mInvVP; +uniform mat4 mView; +uniform mat4 mProj; +uniform mat4 mInvView; +uniform mat4 mInvProj; + +in vec3 position; +out vec4 fColor; +void main() +{ + fColor = vec4(0.89, 0.57, 0.15, 1.0); +} +)" diff --git a/zenovis/src/bate/shader/edge.vert b/zenovis/src/bate/shader/edge.vert new file mode 100644 index 0000000000..a78ad397af --- /dev/null +++ b/zenovis/src/bate/shader/edge.vert @@ -0,0 +1,21 @@ +R"(#version 330 + +uniform mat4 mVP; +uniform mat4 mInvVP; +uniform mat4 mView; +uniform mat4 mProj; +uniform mat4 mInvView; +uniform mat4 mInvProj; + +in vec3 vPosition; + +out vec3 position; +out vec3 color; + +void main() +{ + position = vPosition; + + gl_Position = mVP * vec4(position, 1.0); +} +)"