@@ -72,28 +72,57 @@ void Game::DrawSelectionLine(irr::video::S3DVertex* vec, bool stipple, irr::vide
7272 oldWorld.transformVect (wp[i], vec[i].Pos );
7373 const irr::core::matrix4& view = driver->getTransform (irr::video::ETS_VIEW );
7474 const irr::core::vector3df camFwd (view (0 ,2 ), view (1 ,2 ), view (2 ,2 ));
75- const irr::f32 halfThick = matManager.mOutLine .Thickness * 0 .005f ;
75+ const irr::f32 halfThick = matManager.mOutLine .Thickness * 0 .0025f ;
7676 std::vector<irr::video::S3DVertex> vertices;
7777 std::vector<irr::u16 > indices;
78- vertices.reserve (64 );
79- indices.reserve (96 );
80- constexpr size_t MAX_THICK_LINE_BATCH_VERTICES = (1 << (sizeof (irr::u16 ) * 8 )) - 4 ;
81- const auto appendThickLine = [&](const irr::core::vector3df& start, const irr::core::vector3df& end) {
82- if (vertices.size () > MAX_THICK_LINE_BATCH_VERTICES )
78+ vertices.reserve (128 );
79+ indices.reserve (240 );
80+ constexpr size_t THICK_LINE_VERTICES_PER_SEGMENT = 8 ;
81+ constexpr size_t MAX_THICK_LINE_BATCH_VERTICES = (size_t {1 } << (sizeof (irr::u16 ) * 8 )) - THICK_LINE_VERTICES_PER_SEGMENT ;
82+ const auto drawBatch = [&]() {
83+ if (indices.empty ())
8384 return ;
85+ driver->drawVertexPrimitiveList (vertices.data (), static_cast <irr::u32 >(vertices.size ()),
86+ indices.data (), static_cast <irr::u32 >(indices.size () / 3 ),
87+ irr::video::EVT_STANDARD , irr::scene::EPT_TRIANGLES );
88+ vertices.clear ();
89+ indices.clear ();
90+ };
91+ const auto appendThickLine = [&](const irr::core::vector3df& start, const irr::core::vector3df& end) {
92+ if (halfThick <= 0 .0f ) return ;
8493 const auto direction = end - start;
94+ const irr::f32 dirLenSq = direction.getLengthSQ ();
95+ if (dirLenSq < 1e-12f ) return ;
96+ if (vertices.size () > MAX_THICK_LINE_BATCH_VERTICES )
97+ drawBatch ();
98+ const irr::core::vector3df dir = direction * (1 .0f / std::sqrt (dirLenSq));
8599 irr::core::vector3df perp = direction.crossProduct (camFwd);
86100 const irr::f32 lenSq = perp.getLengthSQ ();
87101 if (lenSq < 1e-12f ) return ;
88102 perp *= halfThick / std::sqrt (lenSq);
103+ const irr::f32 feather = halfThick * 2 .0f ;
104+ const auto outerPerp = perp * ((halfThick + feather) / halfThick);
105+ const auto endFeather = dir * feather;
89106 const auto base = static_cast <irr::u16 >(vertices.size ());
90- static const irr::u16 idx[6 ] = {0 , 2 , 1 , 1 , 2 , 3 };
107+ static const irr::u16 idx[30 ] = {
108+ 0 , 1 , 3 , 0 , 3 , 2 ,
109+ 4 , 5 , 0 , 0 , 5 , 1 ,
110+ 5 , 6 , 1 , 1 , 6 , 3 ,
111+ 6 , 7 , 3 , 3 , 7 , 2 ,
112+ 7 , 4 , 2 , 2 , 4 , 0
113+ };
91114 const irr::core::vector3df normal (0 .0f , 0 .0f , -1 .0f );
115+ irr::video::SColor transparent = color;
116+ transparent.setAlpha (0 );
92117 vertices.emplace_back (start + perp, normal, color, irr::core::vector2df ());
93- vertices.emplace_back (start - perp, normal, color, irr::core::vector2df ());
94118 vertices.emplace_back (end + perp, normal, color, irr::core::vector2df ());
119+ vertices.emplace_back (start - perp, normal, color, irr::core::vector2df ());
95120 vertices.emplace_back (end - perp, normal, color, irr::core::vector2df ());
96- for (int i = 0 ; i < 6 ; ++i)
121+ vertices.emplace_back (start - endFeather + outerPerp, normal, transparent, irr::core::vector2df ());
122+ vertices.emplace_back (end + endFeather + outerPerp, normal, transparent, irr::core::vector2df ());
123+ vertices.emplace_back (end + endFeather - outerPerp, normal, transparent, irr::core::vector2df ());
124+ vertices.emplace_back (start - endFeather - outerPerp, normal, transparent, irr::core::vector2df ());
125+ for (int i = 0 ; i < 30 ; ++i)
97126 indices.push_back (base + idx[i]);
98127 };
99128 driver->setTransform (irr::video::ETS_WORLD , irr::core::matrix4 ());
@@ -143,11 +172,7 @@ void Game::DrawSelectionLine(irr::video::S3DVertex* vec, bool stipple, irr::vide
143172 patternCursor = std::fmod (patternCursor + screenLen, 16 .0f );
144173 }
145174 }
146- if (!indices.empty ()) {
147- driver->drawVertexPrimitiveList (vertices.data (), static_cast <irr::u32 >(vertices.size ()),
148- indices.data (), static_cast <irr::u32 >(indices.size () / 3 ),
149- irr::video::EVT_STANDARD , irr::scene::EPT_TRIANGLES );
150- }
175+ drawBatch ();
151176 driver->setTransform (irr::video::ETS_WORLD , oldWorld);
152177}
153178void Game::DrawSelectionLine (irr::gui::IGUIElement* element, int width, irr::video::SColor color) {
0 commit comments