Cache system doesnt break when transforming objects
This commit is contained in:
parent
caea747f1e
commit
eb00125f01
9 changed files with 101 additions and 95 deletions
|
|
@ -106,9 +106,9 @@ void BrushTool::tool_update() {
|
|||
controls.intermediateItem->d.hasRoundCaps = controls.hasRoundCaps;
|
||||
controls.intermediateItem->coords = drawP.world.drawData.cam.c;
|
||||
controls.intermediateItem->lastUpdateTime = std::chrono::steady_clock::now();
|
||||
controls.intermediateItem->temp_update(drawP);
|
||||
uint64_t placement = drawP.components.client_list().size();
|
||||
controls.intermediateID = drawP.components.client_insert(placement, controls.intermediateItem);
|
||||
controls.intermediateItem->temp_update(drawP);
|
||||
controls.intermediateItem->client_send_place(drawP, placement);
|
||||
// NOTE: The data isnt finallized at this point, so a BVH isn't generated for an object that you undo while youre drawing (this isnt just for brush strokes)
|
||||
// The fix for now is to generate a BVH for an object when you redo it
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ void DrawingProgram::parallel_loop_all_components(std::function<void(const std::
|
|||
void DrawingProgram::check_all_collisions_base(const SCollision::ColliderCollection<WorldScalar>& checkAgainstWorld, const SCollision::ColliderCollection<float>& checkAgainstCam) {
|
||||
for(auto& c : components.client_list())
|
||||
c->obj->globalCollisionCheck = false;
|
||||
compCache.traverse_bvh_run_function(checkAgainstWorld.bounds, [&](DrawingProgramCache::BVHNode* node, const std::vector<CollabListType::ObjectInfoPtr>& comps) {
|
||||
compCache.traverse_bvh_run_function(checkAgainstWorld.bounds, [&](const std::shared_ptr<DrawingProgramCache::BVHNode>& node, const std::vector<CollabListType::ObjectInfoPtr>& comps) {
|
||||
for(auto& c : comps)
|
||||
c->obj->globalCollisionCheck = c->obj->collides_with(world.drawData.cam.c, checkAgainstWorld, checkAgainstCam, colliderAllocated);
|
||||
return true;
|
||||
|
|
@ -447,8 +447,9 @@ void DrawingProgram::initialize_draw_data(cereal::PortableBinaryInputArchive& a)
|
|||
auto newComp = DrawComponent::allocate_comp_type(t);
|
||||
a(newComp->coords, *newComp);
|
||||
components.init_emplace_back(id, newComp);
|
||||
newComp->final_update_dont_invalidate_cache(*this);
|
||||
newComp->final_update(*this);
|
||||
}
|
||||
compCache.force_rebuild();
|
||||
}
|
||||
|
||||
void DrawingProgram::reset_selection() {
|
||||
|
|
@ -607,9 +608,9 @@ void DrawingProgram::draw_components_to_canvas(SkCanvas* canvas, const DrawData&
|
|||
for(auto& c : components.client_list())
|
||||
c->obj->drawSetupData.shouldDraw = false;
|
||||
|
||||
std::vector<DrawingProgramCache::BVHNode*> cachedNodesToDraw;
|
||||
std::vector<std::shared_ptr<DrawingProgramCache::BVHNode>> cachedNodesToDraw;
|
||||
|
||||
compCache.traverse_bvh_run_function(drawData.cam.viewingAreaGenerousCollider, [&](DrawingProgramCache::BVHNode* node, const std::vector<CollabListType::ObjectInfoPtr>& comps) {
|
||||
compCache.traverse_bvh_run_function(drawData.cam.viewingAreaGenerousCollider, [&](const std::shared_ptr<DrawingProgramCache::BVHNode>& node, const std::vector<CollabListType::ObjectInfoPtr>& comps) {
|
||||
if(!dontUseCache && node && node->drawCache && node->coords.inverseScale <= drawData.cam.c.inverseScale) {
|
||||
cachedNodesToDraw.emplace_back(node);
|
||||
return false;
|
||||
|
|
@ -622,7 +623,7 @@ void DrawingProgram::draw_components_to_canvas(SkCanvas* canvas, const DrawData&
|
|||
for(uint64_t i = 0; i < components.client_list().size(); i++) {
|
||||
auto& c = components.client_list()[i];
|
||||
c->obj->draw(canvas, drawData);
|
||||
for(DrawingProgramCache::BVHNode* bvhNode : cachedNodesToDraw) {
|
||||
for(const std::shared_ptr<DrawingProgramCache::BVHNode>& bvhNode : cachedNodesToDraw) {
|
||||
auto& drawCache = bvhNode->drawCache.value();
|
||||
if(drawCache.lastDrawnComponentPlacement == i) {
|
||||
canvas->save();
|
||||
|
|
|
|||
|
|
@ -15,25 +15,33 @@
|
|||
|
||||
DrawingProgramCache::DrawingProgramCache(DrawingProgram& initDrawP):
|
||||
drawP(initDrawP)
|
||||
{}
|
||||
{
|
||||
lastBvhBuildTime = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void DrawingProgramCache::build(std::vector<CollabListType::ObjectInfoPtr> components) {
|
||||
bvhRoot = BVHNode();
|
||||
bvhRoot = std::make_shared<BVHNode>();
|
||||
unsortedComponents.clear();
|
||||
nodesWithCachedSurfaces.clear();
|
||||
std::erase_if(components, [&](auto& c) {
|
||||
if(!c->obj->worldAABB || c->obj->updateDraw) {
|
||||
unsortedComponents.emplace_back(c);
|
||||
c->obj->parentBvhNode.reset();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
build_bvh_node(bvhRoot, components);
|
||||
lastBvhBuildTime = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void DrawingProgramCache::update() {
|
||||
if(unsortedComponents.size() >= 750)
|
||||
build(drawP.components.client_list());
|
||||
if(unsortedComponents.size() >= 750 && (std::chrono::steady_clock::now() - lastBvhBuildTime) >= std::chrono::seconds(7))
|
||||
force_rebuild();
|
||||
}
|
||||
|
||||
void DrawingProgramCache::force_rebuild() {
|
||||
build(drawP.components.client_list());
|
||||
}
|
||||
|
||||
void DrawingProgramCache::add_component(const CollabListType::ObjectInfoPtr& c) {
|
||||
|
|
@ -42,84 +50,73 @@ void DrawingProgramCache::add_component(const CollabListType::ObjectInfoPtr& c)
|
|||
}
|
||||
|
||||
void DrawingProgramCache::erase_component(const CollabListType::ObjectInfoPtr& c) {
|
||||
auto it = std::find(unsortedComponents.begin(), unsortedComponents.end(), c);
|
||||
if(it != unsortedComponents.end())
|
||||
unsortedComponents.erase(it);
|
||||
else {
|
||||
if(!c->obj->worldAABB.has_value())
|
||||
return;
|
||||
auto bvhNodePair = get_bvh_node_fully_containing_recursive(bvhRoot, c->obj.get());
|
||||
if(bvhNodePair.first)
|
||||
bvhNodePair.first->components.erase(bvhNodePair.second);
|
||||
auto parentBvhNode = c->obj->parentBvhNode.lock();
|
||||
if(parentBvhNode) {
|
||||
std::erase(parentBvhNode->components, c);
|
||||
c->obj->parentBvhNode.reset();
|
||||
}
|
||||
else
|
||||
std::erase(unsortedComponents, c);
|
||||
invalidate_cache_before_pos(c->pos);
|
||||
}
|
||||
|
||||
std::pair<DrawingProgramCache::BVHNode*, std::vector<DrawingProgramCache::CollabListType::ObjectInfoPtr>::iterator> DrawingProgramCache::get_bvh_node_fully_containing_recursive(BVHNode& bvhNode, DrawComponent* c) {
|
||||
std::pair<std::shared_ptr<DrawingProgramCache::BVHNode>, std::vector<DrawingProgramCache::CollabListType::ObjectInfoPtr>::iterator> DrawingProgramCache::get_bvh_node_fully_containing_recursive(const std::shared_ptr<BVHNode>& bvhNode, DrawComponent* c) {
|
||||
SCollision::AABB<WorldScalar>& cAABB = c->worldAABB.value();
|
||||
if(!bvhNode.bounds.fully_contains_aabb(cAABB))
|
||||
return {nullptr, bvhNode.components.end()};
|
||||
auto it = std::find_if(bvhNode.components.begin(), bvhNode.components.end(), [&](const auto& comp) {
|
||||
if(!bvhNode->bounds.fully_contains_aabb(cAABB))
|
||||
return {nullptr, bvhNode->components.end()};
|
||||
auto it = std::find_if(bvhNode->components.begin(), bvhNode->components.end(), [&](const auto& comp) {
|
||||
return comp->obj.get() == c;
|
||||
});
|
||||
if(it != bvhNode.components.end())
|
||||
return {&bvhNode, it};
|
||||
for(auto& p : bvhNode.children) {
|
||||
if(it != bvhNode->components.end())
|
||||
return {bvhNode, it};
|
||||
for(auto& p : bvhNode->children) {
|
||||
auto toRet = get_bvh_node_fully_containing_recursive(p, c);
|
||||
if(toRet.first)
|
||||
return toRet;
|
||||
}
|
||||
return {nullptr, bvhNode.components.end()};
|
||||
return {nullptr, bvhNode->components.end()};
|
||||
}
|
||||
|
||||
void DrawingProgramCache::traverse_bvh_run_function(const SCollision::AABB<WorldScalar>& aabb, std::function<bool(BVHNode* node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f) {
|
||||
void DrawingProgramCache::traverse_bvh_run_function(const SCollision::AABB<WorldScalar>& aabb, std::function<bool(const std::shared_ptr<BVHNode> node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f) {
|
||||
f(nullptr, unsortedComponents);
|
||||
traverse_bvh_run_function_recursive(bvhRoot, aabb, f);
|
||||
}
|
||||
|
||||
void DrawingProgramCache::traverse_bvh_run_function_recursive(BVHNode& bvhNode, const SCollision::AABB<WorldScalar>& aabb, std::function<bool(BVHNode* node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f) {
|
||||
if(SCollision::collide(aabb, bvhNode.bounds) && f(&bvhNode, bvhNode.components)) {
|
||||
for(auto& p : bvhNode.children)
|
||||
void DrawingProgramCache::traverse_bvh_run_function_recursive(const std::shared_ptr<BVHNode>& bvhNode, const SCollision::AABB<WorldScalar>& aabb, std::function<bool(const std::shared_ptr<BVHNode>& node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f) {
|
||||
if(bvhNode && SCollision::collide(aabb, bvhNode->bounds) && f(bvhNode, bvhNode->components)) {
|
||||
for(auto& p : bvhNode->children)
|
||||
traverse_bvh_run_function_recursive(p, aabb, f);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingProgramCache::preupdate_component(DrawComponent* c) {
|
||||
auto it = std::find_if(unsortedComponents.begin(), unsortedComponents.end(), [&](const auto& comp) {
|
||||
return comp->obj.get() == c;
|
||||
});
|
||||
if(it != unsortedComponents.end()) {
|
||||
invalidate_cache_before_pos((*it)->pos);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if(!c->worldAABB.has_value())
|
||||
return;
|
||||
auto bvhNodePair = get_bvh_node_fully_containing_recursive(bvhRoot, c);
|
||||
if(bvhNodePair.first) {
|
||||
unsortedComponents.emplace_back(*bvhNodePair.second);
|
||||
invalidate_cache_before_pos((*bvhNodePair.second)->pos);
|
||||
bvhNodePair.first->components.erase(bvhNodePair.second);
|
||||
}
|
||||
void DrawingProgramCache::preupdate_component(const CollabListType::ObjectInfoPtr& c) {
|
||||
auto parentBvhNode = c->obj->parentBvhNode.lock();
|
||||
if(parentBvhNode) {
|
||||
unsortedComponents.emplace_back(c);
|
||||
std::erase(parentBvhNode->components, c);
|
||||
c->obj->parentBvhNode.reset();
|
||||
}
|
||||
invalidate_cache_before_pos(c->pos);
|
||||
}
|
||||
|
||||
void DrawingProgramCache::build_bvh_node(BVHNode& node, std::vector<CollabListType::ObjectInfoPtr> components) {
|
||||
void DrawingProgramCache::build_bvh_node(const std::shared_ptr<BVHNode>& bvhNode, std::vector<CollabListType::ObjectInfoPtr> components) {
|
||||
if(components.empty())
|
||||
return;
|
||||
|
||||
node.bounds = components.front()->obj->worldAABB.value();
|
||||
bvhNode->bounds = components.front()->obj->worldAABB.value();
|
||||
for(auto& c : components)
|
||||
node.bounds.include_aabb_in_bounds(c->obj->worldAABB.value());
|
||||
bvhNode->bounds.include_aabb_in_bounds(c->obj->worldAABB.value());
|
||||
|
||||
build_bvh_node_coords_and_resolution(node);
|
||||
build_bvh_node_coords_and_resolution(*bvhNode);
|
||||
|
||||
if(components.size() < 100) {
|
||||
node.components = components;
|
||||
bvhNode->components = components;
|
||||
for(auto& c : bvhNode->components)
|
||||
c->obj->parentBvhNode = bvhNode;
|
||||
return;
|
||||
}
|
||||
|
||||
WorldVec boundsCenter = node.bounds.center();
|
||||
WorldVec boundsCenter = bvhNode->bounds.center();
|
||||
|
||||
std::array<std::vector<CollabListType::ObjectInfoPtr>, 4> parts;
|
||||
|
||||
|
|
@ -133,13 +130,15 @@ void DrawingProgramCache::build_bvh_node(BVHNode& node, std::vector<CollabListTy
|
|||
parts[2].emplace_back(c);
|
||||
else if(cAABB.min.x() > boundsCenter.x() && cAABB.max.x() > boundsCenter.x() && cAABB.min.y() > boundsCenter.y() && cAABB.max.y() > boundsCenter.y())
|
||||
parts[3].emplace_back(c);
|
||||
else
|
||||
node.components.emplace_back(c);
|
||||
else {
|
||||
bvhNode->components.emplace_back(c);
|
||||
c->obj->parentBvhNode = bvhNode;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& p : parts) {
|
||||
if(!p.empty())
|
||||
build_bvh_node(node.children.emplace_back(), p);
|
||||
build_bvh_node(bvhNode->children.emplace_back(std::make_shared<BVHNode>()), p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -184,8 +183,8 @@ void DrawingProgramCache::invalidate_cache_before_pos(uint64_t placementToInvali
|
|||
}
|
||||
|
||||
void DrawingProgramCache::refresh_all_draw_cache(SkCanvas* canvas, const DrawData& drawData) {
|
||||
std::deque<BVHNode*> nodeFlatList; // We want to render children before parents, so that parents can make use of the cached children
|
||||
traverse_bvh_run_function(drawData.cam.viewingAreaGenerousCollider, [&](DrawingProgramCache::BVHNode* node, const std::vector<CollabListType::ObjectInfoPtr>& comps) {
|
||||
std::deque<std::shared_ptr<BVHNode>> nodeFlatList; // We want to render children before parents, so that parents can make use of the cached children
|
||||
traverse_bvh_run_function(drawData.cam.viewingAreaGenerousCollider, [&](std::shared_ptr<DrawingProgramCache::BVHNode> node, const std::vector<CollabListType::ObjectInfoPtr>& comps) {
|
||||
if(node && node->coords.inverseScale <= drawData.cam.c.inverseScale) {
|
||||
if(!node->drawCache)
|
||||
nodeFlatList.emplace_front(node);
|
||||
|
|
@ -194,17 +193,17 @@ void DrawingProgramCache::refresh_all_draw_cache(SkCanvas* canvas, const DrawDat
|
|||
return true;
|
||||
});
|
||||
if(!nodeFlatList.empty())
|
||||
refresh_draw_cache(*nodeFlatList.front(), drawData);
|
||||
refresh_draw_cache(nodeFlatList.front(), drawData);
|
||||
}
|
||||
|
||||
void DrawingProgramCache::refresh_draw_cache(BVHNode& bvhNode, const DrawData& drawData) {
|
||||
if(bvhNode.children.empty() && bvhNode.components.empty())
|
||||
void DrawingProgramCache::refresh_draw_cache(const std::shared_ptr<BVHNode>& bvhNode, const DrawData& drawData) {
|
||||
if(bvhNode->children.empty() && bvhNode->components.empty())
|
||||
return;
|
||||
|
||||
bvhNode.drawCache = std::nullopt;
|
||||
bvhNode->drawCache = std::nullopt;
|
||||
BVHNode::DrawCacheData drawCache;
|
||||
|
||||
SkImageInfo imgInfo = SkImageInfo::MakeN32Premul(bvhNode.resolution.x(), bvhNode.resolution.y());
|
||||
SkImageInfo imgInfo = SkImageInfo::MakeN32Premul(bvhNode->resolution.x(), bvhNode->resolution.y());
|
||||
#ifdef USE_SKIA_BACKEND_GRAPHITE
|
||||
drawCache.surface = SkSurfaces::RenderTarget(drawP.world.main.window.recorder(), imgInfo, skgpu::Mipmapped::kNo, drawP.world.main.window.defaultMSAASurfaceProps);
|
||||
#elif USE_SKIA_BACKEND_GANESH
|
||||
|
|
@ -219,25 +218,26 @@ void DrawingProgramCache::refresh_draw_cache(BVHNode& bvhNode, const DrawData& d
|
|||
cacheCanvas->clear(SkColor4f{0, 0, 0, 0});
|
||||
|
||||
DrawData cacheDrawData = drawData;
|
||||
cacheDrawData.cam.c = bvhNode.coords;
|
||||
cacheDrawData.cam.c = bvhNode->coords;
|
||||
cacheDrawData.cam.changed = nullptr;
|
||||
cacheDrawData.cam.set_viewing_area(bvhNode.resolution.cast<float>());
|
||||
cacheDrawData.cam.set_viewing_area(bvhNode->resolution.cast<float>());
|
||||
cacheDrawData.refresh_draw_optimizing_values();
|
||||
drawP.draw_components_to_canvas(cacheCanvas, cacheDrawData, false);
|
||||
|
||||
drawCache.lastDrawnComponentPlacement = drawP.components.client_list().size() - 1;
|
||||
drawCache.lastRenderTime = std::chrono::steady_clock::now();
|
||||
|
||||
bvhNode.drawCache = drawCache; // Set the drawCache after rendering is done, so that the draw function doesnt assume we have this node cached
|
||||
bvhNode->drawCache = drawCache; // Set the drawCache after rendering is done, so that the draw function doesnt assume we have this node cached
|
||||
|
||||
while(nodesWithCachedSurfaces.size() >= MAXIMUM_DRAW_CACHE_SURFACES) {
|
||||
BVHNode* leastUsedNode = *nodesWithCachedSurfaces.begin();
|
||||
for(BVHNode* n : nodesWithCachedSurfaces) {
|
||||
std::shared_ptr<BVHNode> leastUsedNode = *nodesWithCachedSurfaces.begin();
|
||||
for(const std::shared_ptr<BVHNode>& n : nodesWithCachedSurfaces) {
|
||||
if(n->drawCache.value().lastRenderTime < leastUsedNode->drawCache.value().lastRenderTime)
|
||||
leastUsedNode = n;
|
||||
}
|
||||
leastUsedNode->drawCache = std::nullopt;
|
||||
nodesWithCachedSurfaces.erase(leastUsedNode);
|
||||
}
|
||||
|
||||
nodesWithCachedSurfaces.emplace(&bvhNode);
|
||||
nodesWithCachedSurfaces.emplace(bvhNode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include "../CollabList.hpp"
|
||||
#include "../DrawComponents/DrawComponent.hpp"
|
||||
#include <include/core/SkSurface.h>
|
||||
#include <unordered_set>
|
||||
#include "../DrawData.hpp"
|
||||
|
||||
class DrawingProgram;
|
||||
|
||||
class DrawComponent;
|
||||
|
||||
class DrawingProgramCache {
|
||||
public:
|
||||
typedef CollabList<std::shared_ptr<DrawComponent>, ServerClientID> CollabListType;
|
||||
|
|
@ -20,7 +22,7 @@ class DrawingProgramCache {
|
|||
struct BVHNode {
|
||||
SCollision::AABB<WorldScalar> bounds;
|
||||
std::vector<CollabListType::ObjectInfoPtr> components;
|
||||
std::vector<BVHNode> children;
|
||||
std::vector<std::shared_ptr<BVHNode>> children;
|
||||
|
||||
CoordSpaceHelper coords;
|
||||
Vector2i resolution;
|
||||
|
|
@ -33,25 +35,28 @@ class DrawingProgramCache {
|
|||
std::optional<DrawCacheData> drawCache;
|
||||
};
|
||||
|
||||
std::unordered_set<BVHNode*> nodesWithCachedSurfaces;
|
||||
std::unordered_set<std::shared_ptr<BVHNode>> nodesWithCachedSurfaces;
|
||||
|
||||
void traverse_bvh_run_function(const SCollision::AABB<WorldScalar>& aabb, std::function<bool(BVHNode* node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f);
|
||||
void traverse_bvh_run_function(const SCollision::AABB<WorldScalar>& aabb, std::function<bool(const std::shared_ptr<BVHNode> node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f);
|
||||
void force_rebuild();
|
||||
|
||||
// Run before actually updating the component
|
||||
void preupdate_component(DrawComponent* c);
|
||||
void preupdate_component(const CollabListType::ObjectInfoPtr& c);
|
||||
|
||||
void invalidate_cache_before_pos(uint64_t placementToInvalidateAt);
|
||||
private:
|
||||
void build_bvh_node_coords_and_resolution(BVHNode& node);
|
||||
void refresh_draw_cache(BVHNode& bvhNode, const DrawData& drawData);
|
||||
void refresh_draw_cache(const std::shared_ptr<BVHNode>& bvhNode, const DrawData& drawData);
|
||||
|
||||
void build(std::vector<CollabListType::ObjectInfoPtr> components);
|
||||
|
||||
void traverse_bvh_run_function_recursive(BVHNode& bvhNode, const SCollision::AABB<WorldScalar>& aabb, std::function<bool(BVHNode* node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f);
|
||||
std::pair<DrawingProgramCache::BVHNode*, std::vector<DrawingProgramCache::CollabListType::ObjectInfoPtr>::iterator> get_bvh_node_fully_containing_recursive(BVHNode& bvhNode, DrawComponent* c);
|
||||
std::chrono::steady_clock::time_point lastBvhBuildTime;
|
||||
|
||||
void build_bvh_node(BVHNode& node, std::vector<CollabListType::ObjectInfoPtr> components);
|
||||
BVHNode bvhRoot;
|
||||
void traverse_bvh_run_function_recursive(const std::shared_ptr<BVHNode>& bvhNode, const SCollision::AABB<WorldScalar>& aabb, std::function<bool(const std::shared_ptr<BVHNode>& node, const std::vector<CollabListType::ObjectInfoPtr>& components)> f);
|
||||
std::pair<std::shared_ptr<DrawingProgramCache::BVHNode>, std::vector<DrawingProgramCache::CollabListType::ObjectInfoPtr>::iterator> get_bvh_node_fully_containing_recursive(const std::shared_ptr<BVHNode>& bvhNode, DrawComponent* c);
|
||||
|
||||
void build_bvh_node(const std::shared_ptr<BVHNode>& bvhNode, std::vector<CollabListType::ObjectInfoPtr> components);
|
||||
std::shared_ptr<BVHNode> bvhRoot;
|
||||
std::vector<CollabListType::ObjectInfoPtr> unsortedComponents;
|
||||
DrawingProgram& drawP;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
EllipseDrawTool::EllipseDrawTool(DrawingProgram& initDrawP):
|
||||
drawP(initDrawP)
|
||||
{
|
||||
controls.intermediateItem = std::make_shared<DrawEllipse>();
|
||||
}
|
||||
|
||||
void EllipseDrawTool::gui_toolbox() {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,7 @@
|
|||
|
||||
RectDrawTool::RectDrawTool(DrawingProgram& initDrawP):
|
||||
drawP(initDrawP)
|
||||
{
|
||||
controls.intermediateItem = std::make_shared<DrawRectangle>();
|
||||
}
|
||||
{}
|
||||
|
||||
void RectDrawTool::gui_toolbox() {
|
||||
Toolbar& t = drawP.world.main.toolbar;
|
||||
|
|
@ -114,9 +112,9 @@ void RectDrawTool::tool_update() {
|
|||
controls.intermediateItem->d.fillStrokeMode = static_cast<uint8_t>(controls.fillStrokeMode);
|
||||
controls.intermediateItem->coords = drawP.world.drawData.cam.c;
|
||||
controls.intermediateItem->lastUpdateTime = std::chrono::steady_clock::now();
|
||||
controls.intermediateItem->temp_update(drawP);
|
||||
uint64_t placement = drawP.components.client_list().size();
|
||||
controls.intermediateID = drawP.components.client_insert(placement, controls.intermediateItem);
|
||||
controls.intermediateItem->temp_update(drawP);
|
||||
controls.intermediateItem->client_send_place(drawP, placement);
|
||||
drawP.add_undo_place_component(placement, controls.intermediateItem);
|
||||
controls.drawStage = 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue