diff --git a/code/Scene/Editor/IModifier.h b/code/Scene/Editor/IModifier.h index a07592615..5efedcbe2 100644 --- a/code/Scene/Editor/IModifier.h +++ b/code/Scene/Editor/IModifier.h @@ -60,6 +60,8 @@ class T_DLLCLASS IModifier : public Object virtual void selectionChanged() = 0; + virtual void buttonDown() = 0; + virtual CursorMovedResult cursorMoved( const TransformChain& transformChain, const Vector2& cursorPosition, diff --git a/code/Scene/Editor/Modifiers/RotateModifier.cpp b/code/Scene/Editor/Modifiers/RotateModifier.cpp index b28456a57..235498c5d 100644 --- a/code/Scene/Editor/Modifiers/RotateModifier.cpp +++ b/code/Scene/Editor/Modifiers/RotateModifier.cpp @@ -80,6 +80,10 @@ void RotateModifier::selectionChanged() m_axisEnable = 0; } +void RotateModifier::buttonDown() +{ +} + IModifier::CursorMovedResult RotateModifier::cursorMoved( const TransformChain& transformChain, const Vector2& cursorPosition, diff --git a/code/Scene/Editor/Modifiers/RotateModifier.h b/code/Scene/Editor/Modifiers/RotateModifier.h index b60b5dae3..e7a3c27da 100644 --- a/code/Scene/Editor/Modifiers/RotateModifier.h +++ b/code/Scene/Editor/Modifiers/RotateModifier.h @@ -35,6 +35,8 @@ class RotateModifier : public IModifier virtual void selectionChanged() override final; + virtual void buttonDown() override final; + virtual CursorMovedResult cursorMoved( const TransformChain& transformChain, const Vector2& cursorPosition, diff --git a/code/Scene/Editor/Modifiers/ScaleModifier.cpp b/code/Scene/Editor/Modifiers/ScaleModifier.cpp index 3da8ef9a9..1ce09c0ea 100644 --- a/code/Scene/Editor/Modifiers/ScaleModifier.cpp +++ b/code/Scene/Editor/Modifiers/ScaleModifier.cpp @@ -68,6 +68,10 @@ void ScaleModifier::selectionChanged() m_deltaScale = Vector4::zero(); } +void ScaleModifier::buttonDown() +{ +} + IModifier::CursorMovedResult ScaleModifier::cursorMoved( const TransformChain& transformChain, const Vector2& cursorPosition, diff --git a/code/Scene/Editor/Modifiers/ScaleModifier.h b/code/Scene/Editor/Modifiers/ScaleModifier.h index 544b32c78..5f8bbe59c 100644 --- a/code/Scene/Editor/Modifiers/ScaleModifier.h +++ b/code/Scene/Editor/Modifiers/ScaleModifier.h @@ -34,6 +34,8 @@ class ScaleModifier : public IModifier virtual void selectionChanged() override final; + virtual void buttonDown() override final; + virtual CursorMovedResult cursorMoved( const TransformChain& transformChain, const Vector2& cursorPosition, diff --git a/code/Scene/Editor/Modifiers/TranslateModifier.cpp b/code/Scene/Editor/Modifiers/TranslateModifier.cpp index 1b230b1c1..1abc04c7e 100644 --- a/code/Scene/Editor/Modifiers/TranslateModifier.cpp +++ b/code/Scene/Editor/Modifiers/TranslateModifier.cpp @@ -71,6 +71,10 @@ void TranslateModifier::selectionChanged() } } +void TranslateModifier::buttonDown() +{ +} + IModifier::CursorMovedResult TranslateModifier::cursorMoved( const TransformChain& transformChain, const Vector2& cursorPosition, diff --git a/code/Scene/Editor/Modifiers/TranslateModifier.h b/code/Scene/Editor/Modifiers/TranslateModifier.h index 615d612a1..0ecb347d3 100644 --- a/code/Scene/Editor/Modifiers/TranslateModifier.h +++ b/code/Scene/Editor/Modifiers/TranslateModifier.h @@ -34,6 +34,8 @@ class TranslateModifier : public IModifier virtual void selectionChanged() override final; + virtual void buttonDown() override final; + virtual CursorMovedResult cursorMoved( const TransformChain& transformChain, const Vector2& cursorPosition, diff --git a/code/Scene/Editor/RenderControlModel.cpp b/code/Scene/Editor/RenderControlModel.cpp index 2fb6e9e01..a83ce23ea 100644 --- a/code/Scene/Editor/RenderControlModel.cpp +++ b/code/Scene/Editor/RenderControlModel.cpp @@ -123,6 +123,8 @@ void RenderControlModel::eventButtonDown(ISceneRenderControl* renderControl, ui: worldRayDirection ); + modifier->buttonDown(); + modifierHit = modifier->cursorMoved( transformChain, screenPosition, diff --git a/code/Shape/Editor/Solid/PrimitiveEditModifier.cpp b/code/Shape/Editor/Solid/PrimitiveEditModifier.cpp index 87d15e0cb..83532269b 100644 --- a/code/Shape/Editor/Solid/PrimitiveEditModifier.cpp +++ b/code/Shape/Editor/Solid/PrimitiveEditModifier.cpp @@ -24,8 +24,8 @@ namespace traktor { - namespace shape - { + namespace shape + { T_IMPLEMENT_RTTI_CLASS(L"traktor.shape.PrimitiveEditModifier", PrimitiveEditModifier, scene::IModifier) @@ -48,98 +48,102 @@ void PrimitiveEditModifier::selectionChanged() m_entityAdapters = m_context->getEntities(scene::SceneEditorContext::GfDefault | scene::SceneEditorContext::GfSelectedOnly | scene::SceneEditorContext::GfNoExternalChild); } +void PrimitiveEditModifier::buttonDown() +{ +} + scene::IModifier::CursorMovedResult PrimitiveEditModifier::cursorMoved( - const scene::TransformChain& transformChain, - const Vector2& cursorPosition, - const Vector4& worldRayOrigin, - const Vector4& worldRayDirection + const scene::TransformChain& transformChain, + const Vector2& cursorPosition, + const Vector4& worldRayOrigin, + const Vector4& worldRayDirection ) { - return { true, true }; + return { true, true }; } bool PrimitiveEditModifier::handleCommand(const ui::Command& command) { - if (command == L"Shape.Editor.BrowseMaterial") - { - Ref< db::Instance > materialInstance = m_context->getEditor()->browseInstance(type_of< model::Material >()); - if (materialInstance) - { - for (auto entityAdapter : m_entityAdapters) - { - auto primitiveEntity = dynamic_type_cast< PrimitiveEntity* >(entityAdapter->getEntity()); - if (!primitiveEntity || primitiveEntity->getSelectedMaterial() == model::c_InvalidIndex) - continue; - - auto primitiveEntityData = mandatory_non_null_type_cast< PrimitiveEntityData* >(entityAdapter->getEntityData()); - primitiveEntityData->setMaterial( - primitiveEntity->getSelectedMaterial(), - materialInstance->getGuid() - ); - } - } - return true; - } - else - return false; + if (command == L"Shape.Editor.BrowseMaterial") + { + Ref< db::Instance > materialInstance = m_context->getEditor()->browseInstance(type_of< model::Material >()); + if (materialInstance) + { + for (auto entityAdapter : m_entityAdapters) + { + auto primitiveEntity = dynamic_type_cast< PrimitiveEntity* >(entityAdapter->getEntity()); + if (!primitiveEntity || primitiveEntity->getSelectedMaterial() == model::c_InvalidIndex) + continue; + + auto primitiveEntityData = mandatory_non_null_type_cast< PrimitiveEntityData* >(entityAdapter->getEntityData()); + primitiveEntityData->setMaterial( + primitiveEntity->getSelectedMaterial(), + materialInstance->getGuid() + ); + } + } + return true; + } + else + return false; } bool PrimitiveEditModifier::begin( - const scene::TransformChain& transformChain, - const Vector2& cursorPosition, - const Vector4& worldRayOrigin, - const Vector4& worldRayDirection, - int32_t mouseButton + const scene::TransformChain& transformChain, + const Vector2& cursorPosition, + const Vector4& worldRayOrigin, + const Vector4& worldRayDirection, + int32_t mouseButton ) { - for (auto entityAdapter : m_entityAdapters) - { - auto primitiveEntity = dynamic_type_cast< PrimitiveEntity* >(entityAdapter->getEntity()); - if (!primitiveEntity) - continue; - - const model::Model* model = primitiveEntity->getModel(); - if (!model) - continue; - - Transform transform = entityAdapter->getTransform(); - - Scalar minK(std::numeric_limits< float >::max()); - uint32_t minMaterial = model::c_InvalidIndex; - - for (uint32_t i = 0; i < model->getPolygonCount(); ++i) - { - const model::Polygon& polygon = model->getPolygon(i); - - Winding3 w; - for (uint32_t j = 0; j < polygon.getVertexCount(); ++j) - w.push(transform * model->getVertexPosition(polygon.getVertex(j))); - - Scalar k; - if (w.rayIntersection(worldRayOrigin, worldRayDirection, k)) - { - if (k < minK) - { - minMaterial = polygon.getMaterial(); - minK = k; - } - } - } - - primitiveEntity->setSelectedMaterial(minMaterial); - } - - return false; + for (auto entityAdapter : m_entityAdapters) + { + auto primitiveEntity = dynamic_type_cast< PrimitiveEntity* >(entityAdapter->getEntity()); + if (!primitiveEntity) + continue; + + const model::Model* model = primitiveEntity->getModel(); + if (!model) + continue; + + Transform transform = entityAdapter->getTransform(); + + Scalar minK(std::numeric_limits< float >::max()); + uint32_t minMaterial = model::c_InvalidIndex; + + for (uint32_t i = 0; i < model->getPolygonCount(); ++i) + { + const model::Polygon& polygon = model->getPolygon(i); + + Winding3 w; + for (uint32_t j = 0; j < polygon.getVertexCount(); ++j) + w.push(transform * model->getVertexPosition(polygon.getVertex(j))); + + Scalar k; + if (w.rayIntersection(worldRayOrigin, worldRayDirection, k)) + { + if (k < minK) + { + minMaterial = polygon.getMaterial(); + minK = k; + } + } + } + + primitiveEntity->setSelectedMaterial(minMaterial); + } + + return false; } void PrimitiveEditModifier::apply( - const scene::TransformChain& transformChain, - const Vector2& cursorPosition, - const Vector4& worldRayOrigin, - const Vector4& worldRayDirection, - const Vector4& screenDelta, - const Vector4& viewDelta, - bool snapOverrideEnable + const scene::TransformChain& transformChain, + const Vector2& cursorPosition, + const Vector4& worldRayOrigin, + const Vector4& worldRayDirection, + const Vector4& screenDelta, + const Vector4& viewDelta, + bool snapOverrideEnable ) { } @@ -150,54 +154,54 @@ void PrimitiveEditModifier::end(const scene::TransformChain& transformChain) void PrimitiveEditModifier::draw(render::PrimitiveRenderer* primitiveRenderer) const { - for (auto entityAdapter : m_entityAdapters) - { - auto primitiveEntity = dynamic_type_cast< PrimitiveEntity* >(entityAdapter->getEntity()); - if (!primitiveEntity) - continue; - - uint32_t selected = primitiveEntity->getSelectedMaterial(); - if (selected == model::c_InvalidIndex) - continue; - - const model::Model* model = primitiveEntity->getModel(); - if (!model) - continue; - - for (uint32_t i = 0; i < model->getPolygonCount(); ++i) - { - const model::Polygon& polygon = model->getPolygon(i); - if (polygon.getMaterial() != selected) - continue; - - Winding3 w; - for (uint32_t j = 0; j < polygon.getVertexCount(); ++j) - w.push(model->getVertexPosition(polygon.getVertex(j))); - - Plane wp; - if (!w.getPlane(wp)) - continue; - - primitiveRenderer->pushWorld(entityAdapter->getTransform().toMatrix44()); - - Triangulator().freeze( - w.get(), - wp.normal(), - Triangulator::Mode::Sequential, - [&](size_t i0, size_t i1, size_t i2) { - primitiveRenderer->drawSolidTriangle( - w[(uint32_t)i0], - w[(uint32_t)i1], - w[(uint32_t)i2], - Color4ub(80, 120, 255, 120) - ); - } - ); - - primitiveRenderer->popWorld(); - } - } + for (auto entityAdapter : m_entityAdapters) + { + auto primitiveEntity = dynamic_type_cast< PrimitiveEntity* >(entityAdapter->getEntity()); + if (!primitiveEntity) + continue; + + uint32_t selected = primitiveEntity->getSelectedMaterial(); + if (selected == model::c_InvalidIndex) + continue; + + const model::Model* model = primitiveEntity->getModel(); + if (!model) + continue; + + for (uint32_t i = 0; i < model->getPolygonCount(); ++i) + { + const model::Polygon& polygon = model->getPolygon(i); + if (polygon.getMaterial() != selected) + continue; + + Winding3 w; + for (uint32_t j = 0; j < polygon.getVertexCount(); ++j) + w.push(model->getVertexPosition(polygon.getVertex(j))); + + Plane wp; + if (!w.getPlane(wp)) + continue; + + primitiveRenderer->pushWorld(entityAdapter->getTransform().toMatrix44()); + + Triangulator().freeze( + w.get(), + wp.normal(), + Triangulator::Mode::Sequential, + [&](size_t i0, size_t i1, size_t i2) { + primitiveRenderer->drawSolidTriangle( + w[(uint32_t)i0], + w[(uint32_t)i1], + w[(uint32_t)i2], + Color4ub(80, 120, 255, 120) + ); + } + ); + + primitiveRenderer->popWorld(); + } + } } - } + } } \ No newline at end of file diff --git a/code/Shape/Editor/Solid/PrimitiveEditModifier.h b/code/Shape/Editor/Solid/PrimitiveEditModifier.h index 75475ad85..2642dbd54 100644 --- a/code/Shape/Editor/Solid/PrimitiveEditModifier.h +++ b/code/Shape/Editor/Solid/PrimitiveEditModifier.h @@ -40,6 +40,8 @@ class PrimitiveEditModifier : public scene::IModifier virtual void selectionChanged() override final; + virtual void buttonDown() override final; + virtual CursorMovedResult cursorMoved( const scene::TransformChain& transformChain, const Vector2& cursorPosition, diff --git a/code/Terrain/Editor/TerrainEditModifier.cpp b/code/Terrain/Editor/TerrainEditModifier.cpp index ed371a7d7..ad0cd3f41 100644 --- a/code/Terrain/Editor/TerrainEditModifier.cpp +++ b/code/Terrain/Editor/TerrainEditModifier.cpp @@ -490,6 +490,11 @@ void TerrainEditModifier::selectionChanged() { } +void TerrainEditModifier::buttonDown() +{ + m_editBrushSize = false; +} + scene::IModifier::CursorMovedResult TerrainEditModifier::cursorMoved( const scene::TransformChain& transformChain, const Vector2& cursorPosition, @@ -502,6 +507,7 @@ scene::IModifier::CursorMovedResult TerrainEditModifier::cursorMoved( const Vector4 lastCenter = m_center; bool hot = false; + bool redraw = false; Scalar distance; if (m_heightfield->queryRay( @@ -510,18 +516,37 @@ scene::IModifier::CursorMovedResult TerrainEditModifier::cursorMoved( distance )) { - m_center = (worldRayOrigin + worldRayDirection * distance).xyz1(); + if (!m_editBrushSize) + { + m_center = (worldRayOrigin + worldRayDirection * distance).xyz1(); + redraw = m_center != lastCenter; + } + else + { + const Vector4 currentCenter = (worldRayOrigin + worldRayDirection * distance).xyz1(); + const Scalar distance = (currentCenter - m_center).length(); + m_radius = float(distance); + redraw = true; + } hot = true; } else + { m_center = Vector4::zero(); + redraw = m_center != lastCenter; + } - return { hot, m_center != lastCenter }; + return { hot, redraw }; } bool TerrainEditModifier::handleCommand(const ui::Command& command) { - if (command == L"Terrain.Editor.FlattenUnderSpline") + if (command == L"Terrain.Editor.EditBrushSize") + { + m_editBrushSize = true; + return true; + } + else if (command == L"Terrain.Editor.FlattenUnderSpline") { flattenUnderSpline(); return true; @@ -538,6 +563,9 @@ bool TerrainEditModifier::begin( int32_t mouseButton ) { + if (m_editBrushSize) + return false; + const bool inverted = (ui::Application::getInstance()->getEventLoop()->getAsyncKeyState() & ui::KsControl) != 0; return begin(inverted); } @@ -589,27 +617,25 @@ void TerrainEditModifier::draw(render::PrimitiveRenderer* primitiveRenderer) con if (!m_terrainComponent || !m_heightfield || m_center.w() <= FUZZY_EPSILON) return; - const float radius = m_context->getGuideSize(); - primitiveRenderer->drawSolidPoint(m_center, 8, Color4ub(255, 0, 0, 255)); primitiveRenderer->pushDepthState(false, false, false); - float x0 = m_center.x() + cosf(0.0f) * radius; - float z0 = m_center.z() + sinf(0.0f) * radius; + float x0 = m_center.x() + cosf(0.0f) * m_radius; + float z0 = m_center.z() + sinf(0.0f) * m_radius; float y0 = m_heightfield->getWorldHeight(x0, z0); for (int32_t i = 1; i <= 32; ++i) { const float a = TWO_PI * i / 32.0f; - const float x1 = m_center.x() + cosf(a) * radius; - const float z1 = m_center.z() + sinf(a) * radius; + const float x1 = m_center.x() + cosf(a) * m_radius; + const float z1 = m_center.z() + sinf(a) * m_radius; const float y1 = m_heightfield->getWorldHeight(x1, z1); primitiveRenderer->drawLine( Vector4(x0, y0 + FUZZY_EPSILON, z0, 1.0f), Vector4(x1, y1 + FUZZY_EPSILON, z1, 1.0f), - 1.0f, + 2.0f, Color4ub(255, 0, 0, 180) ); @@ -691,8 +717,7 @@ bool TerrainEditModifier::begin(bool inverted) m_context->setPlaying(false); - float worldRadius = m_context->getGuideSize(); - int32_t gridRadius = int32_t(m_heightfield->getSize() * worldRadius / m_heightfield->getWorldExtent().x()); + const int32_t gridRadius = int32_t(m_heightfield->getSize() * m_radius / m_heightfield->getWorldExtent().x()); float gx, gz; m_heightfield->worldToGrid(m_center.x(), m_center.z(), gx, gz); @@ -740,8 +765,7 @@ void TerrainEditModifier::apply(const Vector4& center) const int32_t size = m_heightfield->getSize(); // Calculate region which needs to be updated. - const float worldRadius = m_context->getGuideSize(); - const int32_t gridRadius = int32_t(size * worldRadius / m_heightfield->getWorldExtent().x()); + const int32_t gridRadius = int32_t(size * m_radius / m_heightfield->getWorldExtent().x()); int32_t mnx = (int32_t)min(std::floor(gx0) - gridRadius, std::floor(gx1) - gridRadius); int32_t mxx = (int32_t)max(std::ceil(gx0) + gridRadius, std::ceil(gx1) + gridRadius); diff --git a/code/Terrain/Editor/TerrainEditModifier.h b/code/Terrain/Editor/TerrainEditModifier.h index 80de7eae9..7b1063cbc 100644 --- a/code/Terrain/Editor/TerrainEditModifier.h +++ b/code/Terrain/Editor/TerrainEditModifier.h @@ -74,6 +74,8 @@ class TerrainEditModifier : public scene::IModifier virtual void selectionChanged() override final; + virtual void buttonDown() override final; + virtual CursorMovedResult cursorMoved( const scene::TransformChain& transformChain, const Vector2& cursorPosition, @@ -153,7 +155,9 @@ class TerrainEditModifier : public scene::IModifier TerrainComponent::VisualizeMode m_visualizeMode; Vector4 m_center; uint32_t m_updateRegion[4]; + float m_radius = 4.0f; bool m_applied; + bool m_editBrushSize = false; bool begin(bool inverted); diff --git a/code/Terrain/Editor/TerrainEditorProfile.cpp b/code/Terrain/Editor/TerrainEditorProfile.cpp index 158b3ac32..2767166d2 100644 --- a/code/Terrain/Editor/TerrainEditorProfile.cpp +++ b/code/Terrain/Editor/TerrainEditorProfile.cpp @@ -31,6 +31,7 @@ void TerrainEditorProfile::getCommands( ) const { outCommands.push_back(ui::Command(L"Terrain.Editor.EditTerrain")); + outCommands.push_back(ui::Command(L"Terrain.Editor.EditBrushSize")); outCommands.push_back(ui::Command(L"Terrain.Editor.AverageBrush")); outCommands.push_back(ui::Command(L"Terrain.Editor.ColorBrush")); outCommands.push_back(ui::Command(L"Terrain.Editor.CutBrush")); diff --git a/resources/runtime/configurations/Traktor.Editor.config b/resources/runtime/configurations/Traktor.Editor.config index 5c5affd42..281919d8b 100644 --- a/resources/runtime/configurations/Traktor.Editor.config +++ b/resources/runtime/configurations/Traktor.Editor.config @@ -981,7 +981,7 @@ Scene.Editor.MoveToEntity - F + KsCommand,F @@ -1171,15 +1171,9 @@ - Terrain.FlushSurfaceCache + Terrain.Editor.EditBrushSize - KsCommand,Q - - - - Terrain.ToggleFollowGround - - KsCommand,F + F