* QE tool mouse move: highlight PlaneSelectables with alt/ctrl+alt, components in component modes
improve bestPlaneIndirect pickup (resolve, when corner is closest) support 2d in class DragPlanes::bestPlaneIndirect
This commit is contained in:
parent
a4b61f88e5
commit
7acdf92d50
|
|
@ -302,6 +302,7 @@ virtual void selectReversedPlanes( Selector& selector, const SelectedPlanes& sel
|
|||
virtual void bestPlaneDirect( SelectionTest& test, Plane3& plane, SelectionIntersection& intersection ) = 0;
|
||||
virtual void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist ) = 0;
|
||||
virtual void selectByPlane( const Plane3& plane ) = 0;
|
||||
virtual void gatherPolygonsByPlane( const Plane3& plane, std::vector<std::vector<Vector3>>& polygons ) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -227,28 +227,28 @@ void bestPlaneIndirect( const AABB& aabb, SelectionTest& test, Plane3& plane, Ve
|
|||
*/
|
||||
|
||||
const std::size_t edges[24] = {
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 3,
|
||||
3, 0,
|
||||
0, 1, // x
|
||||
3, 2,
|
||||
7, 6,
|
||||
4, 5,
|
||||
5, 6,
|
||||
6, 7,
|
||||
2, 1, // y
|
||||
3, 0,
|
||||
6, 5,
|
||||
7, 4,
|
||||
0, 4,
|
||||
1, 5,
|
||||
2, 6,
|
||||
3, 7,
|
||||
4, 0, // z
|
||||
5, 1,
|
||||
6, 2,
|
||||
7, 3,
|
||||
};
|
||||
|
||||
const std::size_t adjacent_planes[24] = {
|
||||
4, 2,
|
||||
4, 0,
|
||||
4, 3,
|
||||
4, 1,
|
||||
5, 2,
|
||||
5, 0,
|
||||
5, 3,
|
||||
5, 2,
|
||||
4, 0,
|
||||
4, 1,
|
||||
5, 0,
|
||||
5, 1,
|
||||
1, 2,
|
||||
2, 0,
|
||||
|
|
@ -256,31 +256,55 @@ void bestPlaneIndirect( const AABB& aabb, SelectionTest& test, Plane3& plane, Ve
|
|||
3, 1,
|
||||
};
|
||||
|
||||
float dot = 1;
|
||||
const bool some_extent_zero = aabb.extents[0] == 0 || aabb.extents[1] == 0 || aabb.extents[2] == 0;
|
||||
for ( std::size_t i = 0; i < 24; ++++i ){
|
||||
Line line( corners[edges[i]], corners[edges[i + 1]] );
|
||||
if( matrix4_clip_line_by_nearplane( test.getVolume().GetViewMatrix(), line ) == 2 ){
|
||||
if( aabb.extents[i / 8] != 0.f && matrix4_clip_line_by_nearplane( test.getVolume().GetViewMatrix(), line ) == 2 ){
|
||||
const Vector3 intersection_new = line_closest_point( line, g_vector3_identity );
|
||||
const float dist_new = vector3_length_squared( intersection_new );
|
||||
if( dist_new < dist ){
|
||||
const float dot_new = fabs( vector3_dot( vector3_normalised( intersection_new ), vector3_normalised( line.end - line.start ) ) );
|
||||
//effective epsilon is rather big: optimized 32 bit build is using doubles implicitly (floats might be straightly checked for equality); same code in brush.h is cool with way smaller epsilon
|
||||
if( dist - dist_new > 1e-2f // new dist noticeably smaller
|
||||
|| ( float_equal_epsilon( dist_new, dist, 1e-2f ) && dot_new < dot ) ){ // or ambiguous case. Resolve it by dot comparison
|
||||
const Plane3& plane1 = planes[adjacent_planes[i]];
|
||||
const Plane3& plane2 = planes[adjacent_planes[i + 1]];
|
||||
if( plane3_distance_to_point( plane1, test.getVolume().getViewer() ) <= 0 ){
|
||||
if( aabb.extents[( ( adjacent_planes[i] >> 1 ) << 1 ) / 2] == 0 ) /* select the other, if zero bound */
|
||||
plane = plane2;
|
||||
else
|
||||
plane = plane1;
|
||||
intersection = intersection_new;
|
||||
dist = dist_new;
|
||||
}
|
||||
else{
|
||||
if( plane3_distance_to_point( plane2, test.getVolume().getViewer() ) <= 0 ){
|
||||
if( aabb.extents[( ( adjacent_planes[i + 1] >> 1 ) << 1 ) / 2] == 0 ) /* select the other, if zero bound */
|
||||
plane = plane1;
|
||||
else
|
||||
plane = plane2;
|
||||
|
||||
auto assign_plane = [&plane, &intersection, intersection_new, &dist, dist_new, &dot, dot_new]( const Plane3& plane_new ){
|
||||
plane = plane_new;
|
||||
intersection = intersection_new;
|
||||
dist = dist_new;
|
||||
dot = dot_new;
|
||||
};
|
||||
|
||||
if( test.getVolume().fill() ){
|
||||
if( plane3_distance_to_point( plane1, test.getVolume().getViewer() ) <= 0 ){
|
||||
if( aabb.extents[adjacent_planes[i] / 2] == 0 ) /* select the other, if zero bound */
|
||||
assign_plane( plane2 );
|
||||
else
|
||||
assign_plane( plane1 );
|
||||
}
|
||||
else if( plane3_distance_to_point( plane2, test.getVolume().getViewer() ) <= 0 ){
|
||||
if( aabb.extents[adjacent_planes[i + 1] / 2] == 0 ) /* select the other, if zero bound */
|
||||
assign_plane( plane1 );
|
||||
else
|
||||
assign_plane( plane2 );
|
||||
}
|
||||
}
|
||||
else if( some_extent_zero || fabs( vector3_length_squared( line.end - line.start ) ) > 1e-3 ){
|
||||
if( fabs( vector3_dot( plane1.normal(), test.getVolume().getViewDir() ) ) < fabs( vector3_dot( plane2.normal(), test.getVolume().getViewDir() ) ) ){
|
||||
if( aabb.extents[adjacent_planes[i] / 2] == 0 ) /* select the other, if zero bound */
|
||||
assign_plane( plane2 );
|
||||
else
|
||||
assign_plane( plane1 );
|
||||
}
|
||||
else{
|
||||
if( aabb.extents[adjacent_planes[i + 1] / 2] == 0 ) /* select the other, if zero bound */
|
||||
assign_plane( plane1 );
|
||||
else
|
||||
assign_plane( plane2 );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -294,9 +318,38 @@ void selectByPlane( const AABB& aabb, const Plane3& plane, const Matrix4& rotati
|
|||
for ( std::size_t i = 0; i < 6; ++i ){
|
||||
if( plane3_equal( plane, planes[i] ) || plane3_equal( plane, plane3_flipped( planes[i] ) ) ){
|
||||
m_selectables[i].setSelected( true );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
void gatherPolygonsByPlane( const AABB& aabb, const Plane3& plane, std::vector<std::vector<Vector3>>& polygons, const Matrix4& rotation = g_matrix4_identity ) const {
|
||||
Vector3 corners[8];
|
||||
aabb_corners_oriented( aabb, rotation, corners );
|
||||
|
||||
Plane3 planes[6];
|
||||
aabb_planes_oriented( aabb, rotation, planes );
|
||||
|
||||
const std::size_t indices[24] = {
|
||||
2, 1, 5, 6, //+x //right
|
||||
3, 7, 4, 0, //-x //left
|
||||
1, 0, 4, 5, //+y //front
|
||||
3, 2, 6, 7, //-y //back
|
||||
0, 1, 2, 3, //+z //top
|
||||
7, 6, 5, 4, //-z //bottom
|
||||
};
|
||||
|
||||
for ( std::size_t i = 0; i < 6; ++i ){
|
||||
if( plane3_equal( plane, planes[i] ) || plane3_equal( plane, plane3_flipped( planes[i] ) ) ){
|
||||
const std::size_t index = i * 4;
|
||||
polygons.emplace_back( std::initializer_list<Vector3>( { corners[indices[index]],
|
||||
corners[indices[index + 1]],
|
||||
corners[indices[index + 2]],
|
||||
corners[indices[index + 3]] } ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AABB evaluateResize( const Vector3& translation ) const {
|
||||
Vector3 min = m_bounds.origin - m_bounds.extents;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
class Selector;
|
||||
class SelectionTest;
|
||||
class SelectionIntersection;
|
||||
|
||||
class ComponentSelectionTestable
|
||||
{
|
||||
|
|
@ -49,6 +50,7 @@ STRING_CONSTANT( Name, "ComponentSelectionTestable" );
|
|||
virtual bool isSelectedComponents() const = 0;
|
||||
virtual void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ) = 0;
|
||||
virtual void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ) = 0;
|
||||
virtual void gatherComponentsHighlight( std::vector<std::vector<Vector3>>& polygons, SelectionIntersection& intersection, SelectionTest& test, SelectionSystem::EComponentMode mode ) const = 0;
|
||||
};
|
||||
|
||||
typedef std::function<void( const Vector3& )> Vector3Callback;
|
||||
|
|
|
|||
|
|
@ -544,6 +544,8 @@ void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSys
|
|||
m_curveCatmullRom.testSelect( selector, test );
|
||||
}
|
||||
}
|
||||
void gatherComponentsHighlight( std::vector<std::vector<Vector3>>& polygons, SelectionIntersection& intersection, SelectionTest& test, SelectionSystem::EComponentMode mode ) const {
|
||||
}
|
||||
|
||||
void transformComponents( const Matrix4& matrix ){
|
||||
if ( m_curveNURBS.isSelected() ) {
|
||||
|
|
|
|||
|
|
@ -1884,6 +1884,11 @@ void selectByPlane( const Plane3& plane ){
|
|||
m_dragPlanes.selectByPlane( m_contained.aabb(), plane, rotation() );
|
||||
}
|
||||
}
|
||||
void gatherPolygonsByPlane( const Plane3& plane, std::vector<std::vector<Vector3>>& polygons ) const {
|
||||
if ( g_lightType == LIGHTTYPE_DOOM3 ) {
|
||||
m_dragPlanes.gatherPolygonsByPlane( m_contained.aabb(), plane, polygons, rotation() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool isSelectedComponents() const {
|
||||
|
|
@ -1906,6 +1911,8 @@ void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ){
|
|||
}
|
||||
void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ){
|
||||
}
|
||||
void gatherComponentsHighlight( std::vector<std::vector<Vector3>>& polygons, SelectionIntersection& intersection, SelectionTest& test, SelectionSystem::EComponentMode mode ) const {
|
||||
}
|
||||
|
||||
void selectedChangedComponent( const Selectable& selectable ){
|
||||
GlobalSelectionSystem().getObserver ( SelectionSystem::eComponent )( selectable );
|
||||
|
|
|
|||
168
radiant/brush.h
168
radiant/brush.h
|
|
@ -1205,7 +1205,7 @@ void testSelect( SelectionTest& test, SelectionIntersection& best ){
|
|||
Winding_testSelect( m_winding, test, best, m_plane.getPlanePoints() );
|
||||
}
|
||||
|
||||
void testSelect_centroid( SelectionTest& test, SelectionIntersection& best ){
|
||||
void testSelect_centroid( SelectionTest& test, SelectionIntersection& best ) const {
|
||||
test.TestPoint( m_centroid, best );
|
||||
}
|
||||
|
||||
|
|
@ -1502,12 +1502,12 @@ inline FaceVertexId next_vertex( const Faces& faces, FaceVertexId faceVertex ){
|
|||
|
||||
class SelectableEdge
|
||||
{
|
||||
public:
|
||||
Vector3 getEdge() const {
|
||||
const Winding& winding = getFace().getWinding();
|
||||
return vector3_mid( winding[m_faceVertex.getVertex()].vertex, winding[Winding_next( winding, m_faceVertex.getVertex() )].vertex );
|
||||
}
|
||||
|
||||
public:
|
||||
Faces& m_faces;
|
||||
FaceVertexId m_faceVertex;
|
||||
|
||||
|
|
@ -1530,11 +1530,11 @@ void testSelect( SelectionTest& test, SelectionIntersection& best ){
|
|||
|
||||
class SelectableVertex
|
||||
{
|
||||
public:
|
||||
Vector3 getVertex() const {
|
||||
return getFace().getWinding()[m_faceVertex.getVertex()].vertex;
|
||||
}
|
||||
|
||||
public:
|
||||
Faces& m_faces;
|
||||
FaceVertexId m_faceVertex;
|
||||
|
||||
|
|
@ -2859,7 +2859,7 @@ void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localT
|
|||
}
|
||||
}
|
||||
|
||||
void testSelect( SelectionTest& test, SelectionIntersection& best ){
|
||||
void testSelect( SelectionTest& test, SelectionIntersection& best ) const {
|
||||
if ( !m_face->isFiltered() ) {
|
||||
m_face->testSelect( test, best );
|
||||
}
|
||||
|
|
@ -3217,46 +3217,48 @@ void testSelect( Selector& selector, SelectionTest& test ){
|
|||
Selector_add( selector, *this, best );
|
||||
}
|
||||
}
|
||||
void gatherComponentsHighlight( std::vector<std::vector<Vector3>>& polygons, SelectionIntersection& intersection, SelectionTest& test ) const {
|
||||
SelectionIntersection best;
|
||||
m_edge->testSelect( test, best );
|
||||
if ( SelectionIntersection_closer( best, intersection ) ) {
|
||||
intersection = best;
|
||||
polygons.clear();
|
||||
polygons.emplace_back( std::initializer_list<Vector3>( { m_edge->getEdge() } ) );
|
||||
}
|
||||
}
|
||||
|
||||
void bestPlaneIndirect( const SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist ) const {
|
||||
void bestPlaneIndirect( const SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, float& dot ) const {
|
||||
const Winding& winding = m_edge->getFace().getWinding();
|
||||
FaceVertexId faceVertex = m_edge->m_faceVertex;
|
||||
Line line( winding[faceVertex.getVertex()].vertex, winding[Winding_next( winding, faceVertex.getVertex() )].vertex );
|
||||
if( matrix4_clip_line_by_nearplane( test.getVolume().GetViewMatrix(), line ) == 2 ){
|
||||
const Vector3 intersection_new = line_closest_point( line, g_vector3_identity );
|
||||
const float dist_new = vector3_length_squared( intersection_new );
|
||||
if( dist_new < dist ){
|
||||
const float dot_new = fabs( vector3_dot( vector3_normalised( intersection_new ), vector3_normalised( line.end - line.start ) ) );
|
||||
if( dist - dist_new > 1e-6f // new dist noticeably smaller
|
||||
|| ( float_equal_epsilon( dist_new, dist, 1e-6f ) && dot_new < dot ) ){ // or ambiguous case. Resolve it by dot comparison
|
||||
const Plane3& plane1 = m_faceInstances[faceVertex.getFace()].getFace().plane3();
|
||||
faceVertex = next_edge( m_edge->m_faces, faceVertex );
|
||||
const Plane3& plane2 = m_faceInstances[faceVertex.getFace()].getFace().plane3();
|
||||
|
||||
auto assign_plane = [&plane, &intersection, intersection_new, &dist, dist_new, &dot, dot_new]( const Plane3& plane_new ){
|
||||
plane = plane_new;
|
||||
intersection = intersection_new;
|
||||
dist = dist_new;
|
||||
dot = dot_new;
|
||||
};
|
||||
|
||||
if( test.getVolume().fill() ){
|
||||
const Plane3& plane1 = m_faceInstances[faceVertex.getFace()].getFace().plane3();
|
||||
if( plane3_distance_to_point( plane1, test.getVolume().getViewer() ) <= 0 ){
|
||||
plane = plane1;
|
||||
intersection = intersection_new;
|
||||
dist = dist_new;
|
||||
}
|
||||
else{
|
||||
faceVertex = next_edge( m_edge->m_faces, faceVertex );
|
||||
const Plane3& plane2 = m_faceInstances[faceVertex.getFace()].getFace().plane3();
|
||||
if( plane3_distance_to_point( plane2, test.getVolume().getViewer() ) <= 0 ){
|
||||
plane = plane2;
|
||||
intersection = intersection_new;
|
||||
dist = dist_new;
|
||||
}
|
||||
}
|
||||
if( plane3_distance_to_point( plane1, test.getVolume().getViewer() ) <= 0 )
|
||||
assign_plane( plane1 );
|
||||
else if( plane3_distance_to_point( plane2, test.getVolume().getViewer() ) <= 0 )
|
||||
assign_plane( plane2 );
|
||||
}
|
||||
else{
|
||||
const Plane3& plane1 = m_faceInstances[faceVertex.getFace()].getFace().plane3();
|
||||
faceVertex = next_edge( m_edge->m_faces, faceVertex );
|
||||
const Plane3& plane2 = m_faceInstances[faceVertex.getFace()].getFace().plane3();
|
||||
if( fabs( vector3_dot( plane1.normal(), test.getVolume().getViewDir() ) ) < fabs( vector3_dot( plane2.normal(), test.getVolume().getViewDir() ) ) ){
|
||||
plane = plane1;
|
||||
intersection = intersection_new;
|
||||
dist = dist_new;
|
||||
}
|
||||
else{
|
||||
plane = plane2;
|
||||
intersection = intersection_new;
|
||||
dist = dist_new;
|
||||
}
|
||||
else if( fabs( vector3_length_squared( line.end - line.start ) ) > 1e-3 ){
|
||||
if( fabs( vector3_dot( plane1.normal(), test.getVolume().getViewDir() ) ) < fabs( vector3_dot( plane2.normal(), test.getVolume().getViewDir() ) ) )
|
||||
assign_plane( plane1 );
|
||||
else
|
||||
assign_plane( plane2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3313,6 +3315,15 @@ void testSelect( Selector& selector, SelectionTest& test ){
|
|||
Selector_add( selector, *this, best );
|
||||
}
|
||||
}
|
||||
void gatherComponentsHighlight( std::vector<std::vector<Vector3>>& polygons, SelectionIntersection& intersection, SelectionTest& test ) const {
|
||||
SelectionIntersection best;
|
||||
m_vertex->testSelect( test, best );
|
||||
if ( SelectionIntersection_closer( best, intersection ) ) {
|
||||
intersection = best;
|
||||
polygons.clear();
|
||||
polygons.emplace_back( std::initializer_list<Vector3>( { m_vertex->getVertex() } ) );
|
||||
}
|
||||
}
|
||||
|
||||
void selectVerticesOfFace( const FaceInstance& faceinstance ){
|
||||
FaceVertexId faceVertex = m_vertex->m_faceVertex;
|
||||
|
|
@ -3320,13 +3331,14 @@ void selectVerticesOfFace( const FaceInstance& faceinstance ){
|
|||
{
|
||||
if( &faceinstance == &m_faceInstances[faceVertex.getFace()] ){
|
||||
setSelected( true );
|
||||
return;
|
||||
}
|
||||
faceVertex = next_vertex( m_vertex->m_faces, faceVertex );
|
||||
}
|
||||
while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
|
||||
}
|
||||
void gather( Brush::VertexModeVertices& vertexModeVertices ) const {
|
||||
vertexModeVertices.emplace_back( m_vertex->getFace().getWinding()[m_vertex->m_faceVertex.getVertex()].vertex, isSelected() );
|
||||
vertexModeVertices.emplace_back( m_vertex->getVertex(), isSelected() );
|
||||
FaceVertexId faceVertex = m_vertex->m_faceVertex;
|
||||
do
|
||||
{
|
||||
|
|
@ -3336,7 +3348,7 @@ void gather( Brush::VertexModeVertices& vertexModeVertices ) const {
|
|||
while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
|
||||
}
|
||||
bool vertex_select( const Vector3& vertex ){
|
||||
if( vector3_length_squared( vertex - m_vertex->getFace().getWinding()[m_vertex->m_faceVertex.getVertex()].vertex ) < ( 0.1 * 0.1 ) ){
|
||||
if( vector3_length_squared( vertex - m_vertex->getVertex() ) < ( 0.1 * 0.1 ) ){
|
||||
setSelected( true );
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3778,6 +3790,71 @@ void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSys
|
|||
break;
|
||||
}
|
||||
}
|
||||
void gatherComponentsHighlight( std::vector<std::vector<Vector3>>& polygons, SelectionIntersection& intersection, SelectionTest& test, SelectionSystem::EComponentMode mode ) const {
|
||||
test.BeginMesh( localToWorld() );
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
case SelectionSystem::eVertex:
|
||||
{
|
||||
for ( const VertexInstance& i : m_vertexInstances )
|
||||
{
|
||||
i.gatherComponentsHighlight( polygons, intersection, test );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SelectionSystem::eEdge:
|
||||
{
|
||||
for ( const EdgeInstance& i : m_edgeInstances )
|
||||
{
|
||||
i.gatherComponentsHighlight( polygons, intersection, test );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SelectionSystem::eFace:
|
||||
{
|
||||
if ( test.getVolume().fill() ) {
|
||||
const Plane3* plane = nullptr;
|
||||
bool newint = false;
|
||||
for ( const FaceInstance& i : m_faceInstances )
|
||||
{
|
||||
SelectionIntersection best;
|
||||
i.testSelect( test, best );
|
||||
if( best.valid() && intersection.equalEpsilon( best, 0.25f, 2e-6f ) ){
|
||||
plane = &i.getFace().plane3();
|
||||
}
|
||||
else if ( SelectionIntersection_closer( best, intersection ) ) {
|
||||
intersection = best;
|
||||
newint = true;
|
||||
plane = &i.getFace().plane3();
|
||||
}
|
||||
}
|
||||
if( plane ){
|
||||
if( newint || ( !polygons.empty() && polygons.back().size() >= 3 && !plane3_equal( *plane, plane3_for_points( polygons.back().data() ) ) ) ){
|
||||
polygons.clear();
|
||||
}
|
||||
gatherPolygonsByPlane( *plane, polygons, false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( const FaceInstance& i : m_faceInstances )
|
||||
{
|
||||
SelectionIntersection best;
|
||||
i.getFace().testSelect_centroid( test, best );
|
||||
if ( SelectionIntersection_closer( best, intersection ) ) {
|
||||
intersection = best;
|
||||
polygons.clear();
|
||||
polygons.emplace_back( std::initializer_list<Vector3>( { i.getFace().centroid() } ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void invertComponentSelection( SelectionSystem::EComponentMode mode ){
|
||||
switch ( mode )
|
||||
|
|
@ -3867,9 +3944,10 @@ void bestPlaneDirect( SelectionTest& test, Plane3& plane, SelectionIntersection&
|
|||
}
|
||||
void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist ){
|
||||
test.BeginMesh( localToWorld() );
|
||||
float dot = 1;
|
||||
for ( EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i )
|
||||
{
|
||||
( *i ).bestPlaneIndirect( test, plane, intersection, dist );
|
||||
( *i ).bestPlaneIndirect( test, plane, intersection, dist, dot );
|
||||
}
|
||||
}
|
||||
void selectByPlane( const Plane3& plane ){
|
||||
|
|
@ -3877,6 +3955,20 @@ void selectByPlane( const Plane3& plane ){
|
|||
if( plane3_equal( plane, fi.getFace().plane3() ) || plane3_equal( plane, plane3_flipped( fi.getFace().plane3() ) ) )
|
||||
fi.setSelected( SelectionSystem::eFace, true );
|
||||
}
|
||||
void gatherPolygonsByPlane( const Plane3& plane, std::vector<std::vector<Vector3>>& polygons ) const {
|
||||
gatherPolygonsByPlane( plane, polygons, true );
|
||||
}
|
||||
void gatherPolygonsByPlane( const Plane3& plane, std::vector<std::vector<Vector3>>& polygons, const bool reversed_plane_also ) const {
|
||||
for ( const FaceInstance& fi : m_faceInstances )
|
||||
if( plane3_equal( plane, fi.getFace().plane3() ) || ( reversed_plane_also && plane3_equal( plane, plane3_flipped( fi.getFace().plane3() ) ) ) )
|
||||
if( fi.getFace().contributes() ){
|
||||
const Winding& winding = fi.getFace().getWinding();
|
||||
polygons.emplace_back( winding.numpoints );
|
||||
for( std::size_t i = 0; i < winding.numpoints; ++i ){
|
||||
polygons.back()[i] = winding[i].vertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void selectVerticesOnPlane( const Plane3& plane ){
|
||||
for ( FaceInstance& fi : m_faceInstances )
|
||||
|
|
|
|||
|
|
@ -906,6 +906,7 @@ void render( RenderStateFlags state ) const {
|
|||
glPolygonOffset( 1, -1 );
|
||||
glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( Colour4b ), colorarr1.data() );
|
||||
glDrawArrays( GL_QUADS, start0? 2 : 0, GLsizei( count - ( start0? 2 : 4 ) ) );
|
||||
glPolygonOffset( -1, 1 ); // restore default
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1543,6 +1543,47 @@ void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ){
|
|||
m_dragPlanes.setSelected( select );
|
||||
}
|
||||
}
|
||||
void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ){
|
||||
test.BeginMesh( localToWorld() );
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
case SelectionSystem::eVertex:
|
||||
{
|
||||
for ( PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i )
|
||||
{
|
||||
( *i ).testSelect( selector, test );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
void gatherComponentsHighlight( std::vector<std::vector<Vector3>>& polygons, SelectionIntersection& intersection, SelectionTest& test, SelectionSystem::EComponentMode mode ) const {
|
||||
test.BeginMesh( localToWorld() );
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
case SelectionSystem::eVertex:
|
||||
{
|
||||
for ( const PatchControlInstance& pci : m_ctrl_instances )
|
||||
{
|
||||
SelectionIntersection best;
|
||||
test.TestPoint( pci.m_ctrl->m_vertex, best );
|
||||
if ( SelectionIntersection_closer( best, intersection ) ) {
|
||||
intersection = best;
|
||||
polygons.clear();
|
||||
polygons.emplace_back( std::initializer_list<Vector3>( { pci.m_ctrl->m_vertex } ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const AABB& getSelectedComponentsBounds() const {
|
||||
m_aabb_component = AABB();
|
||||
|
||||
|
|
@ -1564,26 +1605,8 @@ void gatherSelectedComponents( const Vector3Callback& callback ) const {
|
|||
}
|
||||
}
|
||||
|
||||
void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ){
|
||||
test.BeginMesh( localToWorld() );
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
case SelectionSystem::eVertex:
|
||||
{
|
||||
for ( PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i )
|
||||
{
|
||||
( *i ).testSelect( selector, test );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool selectedVertices(){
|
||||
for ( PatchControlInstances::iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i )
|
||||
bool selectedVertices() const {
|
||||
for ( PatchControlInstances::const_iterator i = m_ctrl_instances.begin(); i != m_ctrl_instances.end(); ++i )
|
||||
{
|
||||
if ( ( *i ).m_selectable.isSelected() ) {
|
||||
return true;
|
||||
|
|
@ -1637,6 +1660,9 @@ void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersectio
|
|||
void selectByPlane( const Plane3& plane ){
|
||||
m_dragPlanes.selectByPlane( m_patch.localAABB(), plane );
|
||||
}
|
||||
void gatherPolygonsByPlane( const Plane3& plane, std::vector<std::vector<Vector3>>& polygons ) const {
|
||||
m_dragPlanes.gatherPolygonsByPlane( m_patch.localAABB(), plane, polygons );
|
||||
}
|
||||
|
||||
|
||||
void snapComponents( float snap ){
|
||||
|
|
|
|||
|
|
@ -2325,6 +2325,20 @@ void OpenGLShader::construct( const char* name ){
|
|||
state.m_sort = OpenGLState::eSortTranslucent;
|
||||
}
|
||||
#endif // 0
|
||||
else if ( string_equal( name + 1, "PLANE_WIRE_OVERLAY" ) ) {
|
||||
state.m_colour = Vector4( 1, 1, 0, 1 );
|
||||
state.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | RENDER_OFFSETLINE;
|
||||
state.m_sort = OpenGLState::eSortGUI1;
|
||||
state.m_depthfunc = GL_LEQUAL;
|
||||
state.m_linewidth = 2;
|
||||
|
||||
OpenGLState& hiddenLine = appendDefaultPass();
|
||||
hiddenLine.m_colour = state.m_colour;
|
||||
hiddenLine.m_state = RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST | RENDER_LINESTIPPLE;
|
||||
hiddenLine.m_sort = OpenGLState::eSortGUI0;
|
||||
hiddenLine.m_depthfunc = GL_GREATER;
|
||||
hiddenLine.m_linestipple_factor = 2;
|
||||
}
|
||||
else if ( string_equal( name + 1, "WIRE_OVERLAY" ) ) {
|
||||
#if 0
|
||||
state.m_state = RENDER_COLOURARRAY | RENDER_COLOURWRITE | RENDER_DEPTHWRITE | RENDER_DEPTHTEST;
|
||||
|
|
|
|||
|
|
@ -407,6 +407,9 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const
|
|||
Vector3 current = g_vector3_axes[m_axisZ] * vector3_dot( m_planeSelected.normal(), ( point_on_plane( m_planeZ, m_view->GetViewMatrix(), x, y ) - m_startZ ) )
|
||||
* ( m_planeSelected.normal()[m_axisZ] >= 0? 1 : -1 );
|
||||
|
||||
if( !std::isfinite( current[0] ) || !std::isfinite( current[1] ) || !std::isfinite( current[2] ) ) // catch INF case, is likely with top of the box in 2D
|
||||
return;
|
||||
|
||||
if( snapbbox )
|
||||
aabb_snap_translation( current, m_bounds );
|
||||
else
|
||||
|
|
@ -2951,10 +2954,7 @@ inline const Functor& Scene_forEachVisibleSelectedPlaneselectable( const Functor
|
|||
return functor;
|
||||
}
|
||||
|
||||
bool Scene_forEachPlaneSelectable_selectPlanes2( SelectionTest& test, TranslateAxis2& translateAxis ){
|
||||
Plane3 plane( 0, 0, 0, 0 );
|
||||
Vector3 intersectionPoint( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
|
||||
void Scene_forEachPlaneSelectable_bestPlane( SelectionTest& test, Plane3& plane, Vector3& intersectionPoint ){
|
||||
SelectionIntersection intersection;
|
||||
auto bestPlaneDirect = [&test, &plane, &intersection]( PlaneSelectable& planeSelectable ){
|
||||
planeSelectable.bestPlaneDirect( test, plane, intersection );
|
||||
|
|
@ -2967,6 +2967,12 @@ bool Scene_forEachPlaneSelectable_selectPlanes2( SelectionTest& test, TranslateA
|
|||
};
|
||||
Scene_forEachVisibleSelectedPlaneselectable( bestPlaneIndirect );
|
||||
}
|
||||
}
|
||||
|
||||
bool Scene_forEachPlaneSelectable_selectPlanes2( SelectionTest& test, TranslateAxis2& translateAxis ){
|
||||
Plane3 plane( 0, 0, 0, 0 );
|
||||
Vector3 intersectionPoint( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
Scene_forEachPlaneSelectable_bestPlane( test, plane, intersectionPoint );
|
||||
|
||||
if( plane3_valid( plane ) ){
|
||||
if( intersectionPoint == Vector3( FLT_MAX, FLT_MAX, FLT_MAX ) ){ // direct
|
||||
|
|
@ -2988,23 +2994,24 @@ bool Scene_forEachPlaneSelectable_selectPlanes2( SelectionTest& test, TranslateA
|
|||
}
|
||||
|
||||
|
||||
bool Scene_forEachBrush_setupExtrude( SelectionTest& test, DragExtrudeFaces& extrudeFaces ){
|
||||
Plane3 plane( 0, 0, 0, 0 );
|
||||
Vector3 intersectionPoint( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
|
||||
if( g_SelectedFaceInstances.empty() ){
|
||||
SelectionIntersection intersection;
|
||||
auto bestPlaneDirect = [&test, &plane, &intersection]( BrushInstance& brushInstance ){
|
||||
brushInstance.bestPlaneDirect( test, plane, intersection );
|
||||
void Scene_forEachSelectedBrush_bestPlane( SelectionTest& test, Plane3& plane, Vector3& intersectionPoint ){
|
||||
SelectionIntersection intersection;
|
||||
auto bestPlaneDirect = [&test, &plane, &intersection]( BrushInstance& brushInstance ){
|
||||
brushInstance.bestPlaneDirect( test, plane, intersection );
|
||||
};
|
||||
Scene_forEachVisibleSelectedBrush( bestPlaneDirect );
|
||||
if( !plane3_valid( plane ) ){
|
||||
float dist( FLT_MAX );
|
||||
auto bestPlaneIndirect = [&test, &plane, &intersectionPoint, &dist]( BrushInstance& brushInstance ){
|
||||
brushInstance.bestPlaneIndirect( test, plane, intersectionPoint, dist );
|
||||
};
|
||||
Scene_forEachVisibleSelectedBrush( bestPlaneDirect );
|
||||
if( !plane3_valid( plane ) ){
|
||||
float dist( FLT_MAX );
|
||||
auto bestPlaneIndirect = [&test, &plane, &intersectionPoint, &dist]( BrushInstance& brushInstance ){
|
||||
brushInstance.bestPlaneIndirect( test, plane, intersectionPoint, dist );
|
||||
};
|
||||
Scene_forEachVisibleSelectedBrush( bestPlaneIndirect );
|
||||
}
|
||||
Scene_forEachVisibleSelectedBrush( bestPlaneIndirect );
|
||||
}
|
||||
}
|
||||
|
||||
void Scene_forEachBrush_bestPlane( SelectionTest& test, Plane3& plane, Vector3& intersectionPoint ){
|
||||
if( g_SelectedFaceInstances.empty() ){
|
||||
Scene_forEachSelectedBrush_bestPlane( test, plane, intersectionPoint );
|
||||
}
|
||||
else{
|
||||
SelectionIntersection intersection;
|
||||
|
|
@ -3023,6 +3030,12 @@ bool Scene_forEachBrush_setupExtrude( SelectionTest& test, DragExtrudeFaces& ext
|
|||
Scene_forEachVisibleBrush( GlobalSceneGraph(), bestPlaneIndirect );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Scene_forEachBrush_setupExtrude( SelectionTest& test, DragExtrudeFaces& extrudeFaces ){
|
||||
Plane3 plane( 0, 0, 0, 0 );
|
||||
Vector3 intersectionPoint( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
Scene_forEachBrush_bestPlane( test, plane, intersectionPoint );
|
||||
|
||||
if( plane3_valid( plane ) ){
|
||||
if( intersectionPoint == Vector3( FLT_MAX, FLT_MAX, FLT_MAX ) ){ // direct
|
||||
|
|
@ -4201,20 +4214,8 @@ bool selection_selectVerticesOrFaceVertices( SelectionTest& test ){
|
|||
}
|
||||
/* otherwise select vertices of brush faces, which lay on best plane */
|
||||
Plane3 plane( 0, 0, 0, 0 );
|
||||
SelectionIntersection intersection;
|
||||
auto bestPlaneDirect = [&test, &plane, &intersection]( BrushInstance& brushInstance ){
|
||||
brushInstance.bestPlaneDirect( test, plane, intersection );
|
||||
};
|
||||
Scene_forEachVisibleSelectedBrush( bestPlaneDirect );
|
||||
|
||||
if( !plane3_valid( plane ) ){
|
||||
Vector3 intersectionPoint;
|
||||
float dist( FLT_MAX );
|
||||
auto bestPlaneIndirect = [&test, &plane, &intersectionPoint, &dist]( BrushInstance& brushInstance ){
|
||||
brushInstance.bestPlaneIndirect( test, plane, intersectionPoint, dist );
|
||||
};
|
||||
Scene_forEachVisibleSelectedBrush( bestPlaneIndirect );
|
||||
}
|
||||
Vector3 intersectionPoint( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
Scene_forEachSelectedBrush_bestPlane( test, plane, intersectionPoint );
|
||||
|
||||
if( plane3_valid( plane ) ){
|
||||
auto selectVerticesOnPlane = [&plane]( BrushInstance& brushInstance ){
|
||||
|
|
@ -4227,6 +4228,29 @@ bool selection_selectVerticesOrFaceVertices( SelectionTest& test ){
|
|||
}
|
||||
|
||||
|
||||
template<typename Functor>
|
||||
class ComponentSelectionTestableVisibleSelectedVisitor : public SelectionSystem::Visitor
|
||||
{
|
||||
const Functor& m_functor;
|
||||
public:
|
||||
ComponentSelectionTestableVisibleSelectedVisitor( const Functor& functor ) : m_functor( functor ){
|
||||
}
|
||||
void visit( scene::Instance& instance ) const {
|
||||
ComponentSelectionTestable* componentSelectionTestable = Instance_getComponentSelectionTestable( instance );
|
||||
if ( componentSelectionTestable != 0
|
||||
&& instance.path().top().get().visible() ) {
|
||||
m_functor( *componentSelectionTestable );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Functor>
|
||||
inline const Functor& Scene_forEachVisibleSelectedComponentSelectionTestable( const Functor& functor ){
|
||||
GlobalSelectionSystem().foreachSelected( ComponentSelectionTestableVisibleSelectedVisitor<Functor>( functor ) );
|
||||
return functor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ModifierFlags g_modifiers = c_modifierNone; //AltDragManipulatorResize, extrude, uvtool skew, select primitives in component modes
|
||||
static bool g_bTmpComponentMode = false;
|
||||
|
|
@ -4247,8 +4271,11 @@ bool m_extrudeFaces;
|
|||
|
||||
public:
|
||||
|
||||
DragManipulator( Translatable& translatable ) : m_freeResize( m_resize ), m_axisResize( m_resize ), m_freeDragXY_Z( translatable ){
|
||||
static Shader* m_state_wire;
|
||||
|
||||
DragManipulator( Translatable& translatable ) : m_freeResize( m_resize ), m_axisResize( m_resize ), m_freeDragXY_Z( translatable ), m_renderCircle( 2 << 3 ){
|
||||
setSelected( false );
|
||||
draw_circle( m_renderCircle.m_vertices.size() >> 3, 5, m_renderCircle.m_vertices.data(), RemapXYZ() );
|
||||
}
|
||||
|
||||
Manipulatable* GetManipulatable(){
|
||||
|
|
@ -4268,16 +4295,18 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
SelectionPool selector;
|
||||
SelectionVolume test( view );
|
||||
|
||||
if( g_modifiers == ( c_modifierAlt | c_modifierControl ) && ( GlobalSelectionSystem().countSelected() != 0 || !g_SelectedFaceInstances.empty() ) ){ // extrude
|
||||
if( g_modifiers == ( c_modifierAlt | c_modifierControl )
|
||||
&& GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive
|
||||
&& ( GlobalSelectionSystem().countSelected() != 0 || !g_SelectedFaceInstances.empty() ) ){ // extrude
|
||||
m_extrudeFaces = Scene_forEachBrush_setupExtrude( test, m_dragExtrudeFaces );
|
||||
}
|
||||
else if( GlobalSelectionSystem().countSelected() != 0 ){
|
||||
if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){
|
||||
if( g_modifiers == c_modifierAlt ){
|
||||
if( view.fill() ){
|
||||
if( view.fill() ){ // alt resize
|
||||
m_selected2 = Scene_forEachPlaneSelectable_selectPlanes2( test, m_axisResize );
|
||||
}
|
||||
else{
|
||||
else{ // alt vertices drag
|
||||
m_selected = selection_selectVerticesOrFaceVertices( test );
|
||||
}
|
||||
}
|
||||
|
|
@ -4295,7 +4324,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
else{ // components
|
||||
BestSelector bestSelector;
|
||||
Scene_TestSelect_Component_Selected( bestSelector, test, view, GlobalSelectionSystem().ComponentMode() ); /* drag components */
|
||||
for ( Selectable* s : bestSelector.best() ){
|
||||
|
|
@ -4353,7 +4382,126 @@ void setSelected( bool select ){
|
|||
bool isSelected() const {
|
||||
return m_dragSelected || m_selected || m_selected2 || m_newBrush || m_extrudeFaces;
|
||||
}
|
||||
|
||||
void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world ){
|
||||
if( !m_polygons.empty() ){
|
||||
renderer.SetState( m_state_wire, Renderer::eWireframeOnly );
|
||||
renderer.SetState( m_state_wire, Renderer::eFullMaterials );
|
||||
if( m_polygons.back().size() == 1 ){
|
||||
Pivot2World_viewplaneSpace( m_renderCircle.m_viewplaneSpace, matrix4_translation_for_vec3( m_polygons.back()[0] ), volume.GetModelview(), volume.GetProjection(), volume.GetViewport() );
|
||||
renderer.addRenderable( m_renderCircle, m_renderCircle.m_viewplaneSpace );
|
||||
}
|
||||
else{
|
||||
renderer.addRenderable( m_renderPoly, g_matrix4_identity );
|
||||
}
|
||||
}
|
||||
}
|
||||
void highlight( const View& view ){
|
||||
SelectionVolume test( view );
|
||||
std::vector<std::vector<Vector3>> polygons;
|
||||
/* conditions structure respects one in testSelect() */
|
||||
if( g_modifiers == ( c_modifierAlt | c_modifierControl )
|
||||
&& GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive
|
||||
&& ( GlobalSelectionSystem().countSelected() != 0 || !g_SelectedFaceInstances.empty() ) ){ // extrude
|
||||
Plane3 plane( 0, 0, 0, 0 );
|
||||
Vector3 intersectionPoint( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
Scene_forEachBrush_bestPlane( test, plane, intersectionPoint );
|
||||
|
||||
if( plane3_valid( plane ) ){
|
||||
auto gatherPolygonsByPlane = [plane, &polygons]( BrushInstance& brushInstance ){
|
||||
if( brushInstance.isSelected() || brushInstance.isSelectedComponents() )
|
||||
brushInstance.gatherPolygonsByPlane( plane, polygons, false );
|
||||
};
|
||||
Scene_forEachVisibleBrush( GlobalSceneGraph(), gatherPolygonsByPlane );
|
||||
}
|
||||
}
|
||||
else if( GlobalSelectionSystem().countSelected() != 0 ){
|
||||
if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){
|
||||
if( g_modifiers == c_modifierAlt ){
|
||||
if( view.fill() ){ // alt resize
|
||||
Plane3 plane( 0, 0, 0, 0 );
|
||||
Vector3 intersectionPoint( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
Scene_forEachPlaneSelectable_bestPlane( test, plane, intersectionPoint );
|
||||
|
||||
if( plane3_valid( plane ) ){
|
||||
auto gatherPolygonsByPlane = [plane, &polygons]( PlaneSelectable& planeSelectable ){
|
||||
planeSelectable.gatherPolygonsByPlane( plane, polygons );
|
||||
};
|
||||
Scene_forEachVisibleSelectedPlaneselectable( gatherPolygonsByPlane );
|
||||
}
|
||||
|
||||
}
|
||||
else{ // alt vertices drag
|
||||
SelectionIntersection intersection;
|
||||
const SelectionSystem::EComponentMode mode = SelectionSystem::eVertex;
|
||||
auto gatherComponentsHighlight = [&polygons, &intersection, &test, mode]( const ComponentSelectionTestable& componentSelectionTestable ){
|
||||
componentSelectionTestable.gatherComponentsHighlight( polygons, intersection, test, mode );
|
||||
};
|
||||
Scene_forEachVisibleSelectedComponentSelectionTestable( gatherComponentsHighlight );
|
||||
|
||||
if( polygons.empty() ){
|
||||
Plane3 plane( 0, 0, 0, 0 );
|
||||
Vector3 intersectionPoint( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
Scene_forEachSelectedBrush_bestPlane( test, plane, intersectionPoint );
|
||||
|
||||
if( plane3_valid( plane ) ){
|
||||
auto gatherPolygonsByPlane = [plane, &polygons]( BrushInstance& brushInstance ){
|
||||
brushInstance.gatherPolygonsByPlane( plane, polygons );
|
||||
};
|
||||
Scene_forEachVisibleSelectedBrush( gatherPolygonsByPlane );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{ // components
|
||||
SelectionIntersection intersection;
|
||||
const SelectionSystem::EComponentMode mode = GlobalSelectionSystem().ComponentMode();
|
||||
auto gatherComponentsHighlight = [&polygons, &intersection, &test, mode]( const ComponentSelectionTestable& componentSelectionTestable ){
|
||||
componentSelectionTestable.gatherComponentsHighlight( polygons, intersection, test, mode );
|
||||
};
|
||||
Scene_forEachVisibleSelectedComponentSelectionTestable( gatherComponentsHighlight );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_polygons != polygons ){
|
||||
m_polygons.swap( polygons );
|
||||
SceneChangeNotify();
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::vector<std::vector<Vector3>> m_polygons;
|
||||
struct RenderablePoly: public OpenGLRenderable
|
||||
{
|
||||
const std::vector<std::vector<Vector3>>& m_polygons;
|
||||
|
||||
RenderablePoly( const std::vector<std::vector<Vector3>>& polygons ) : m_polygons( polygons ){
|
||||
}
|
||||
void render( RenderStateFlags state ) const {
|
||||
glPolygonOffset( -2, -2 );
|
||||
for( const auto& poly : m_polygons ){
|
||||
glVertexPointer( 3, GL_FLOAT, sizeof( m_polygons[0][0] ), poly[0].data() );
|
||||
glDrawArrays( GL_POLYGON, 0, GLsizei( poly.size() ) );
|
||||
}
|
||||
glPolygonOffset( -1, 1 ); // restore default
|
||||
}
|
||||
};
|
||||
RenderablePoly m_renderPoly{ m_polygons };
|
||||
struct RenderableCircle : public OpenGLRenderable
|
||||
{
|
||||
Array<PointVertex> m_vertices;
|
||||
Matrix4 m_viewplaneSpace;
|
||||
|
||||
RenderableCircle( std::size_t size ) : m_vertices( size ){
|
||||
}
|
||||
void render( RenderStateFlags state ) const {
|
||||
glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices.data()->vertex );
|
||||
glDrawArrays( GL_LINE_LOOP, 0, GLsizei( m_vertices.size() ) );
|
||||
}
|
||||
};
|
||||
RenderableCircle m_renderCircle;
|
||||
};
|
||||
Shader* DragManipulator::m_state_wire;
|
||||
|
||||
|
||||
|
||||
|
|
@ -6874,7 +7022,11 @@ bool SelectManipulator( const View& view, const float device_point[2], const flo
|
|||
void HighlightManipulator( const View& view, const float device_point[2], const float device_epsilon[2] ){
|
||||
Manipulatable::assign_static( view, device_point, device_epsilon ); //this b4 m_manipulator calls!
|
||||
|
||||
if ( ( !nothingSelected() && transformOrigin_isTranslatable() ) || ManipulatorMode() == eClip || ManipulatorMode() == eBuild || ManipulatorMode() == eUV ) {
|
||||
if ( ( !nothingSelected() && transformOrigin_isTranslatable() )
|
||||
|| ManipulatorMode() == eClip
|
||||
|| ManipulatorMode() == eBuild
|
||||
|| ManipulatorMode() == eUV
|
||||
|| ManipulatorMode() == eDrag ) {
|
||||
#if defined ( DEBUG_SELECTION )
|
||||
g_render_clipped.destroy();
|
||||
#endif
|
||||
|
|
@ -6900,6 +7052,9 @@ void HighlightManipulator( const View& view, const float device_point[2], const
|
|||
else if( ManipulatorMode() == eUV ){
|
||||
m_manipulator->testSelect( scissored, GetPivot2World() );
|
||||
}
|
||||
else if( ManipulatorMode() == eDrag ){
|
||||
m_drag_manipulator.highlight( scissored );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7358,12 +7513,14 @@ static void constructStatic(){
|
|||
UVManipulator::m_state_point = GlobalShaderCache().capture( "$BIGPOINT" );
|
||||
RenderablePivot::StaticShader::instance() = GlobalShaderCache().capture( "$PIVOT" );
|
||||
UVManipulator::m_state_line = GlobalShaderCache().capture( "$BLENDLINE" );
|
||||
DragManipulator::m_state_wire = GlobalShaderCache().capture( "$PLANE_WIRE_OVERLAY" );
|
||||
}
|
||||
|
||||
static void destroyStatic(){
|
||||
#if defined( DEBUG_SELECTION )
|
||||
GlobalShaderCache().release( "$DEBUG_CLIPPED" );
|
||||
#endif
|
||||
GlobalShaderCache().release( "$PLANE_WIRE_OVERLAY" );
|
||||
GlobalShaderCache().release( "$BLENDLINE" );
|
||||
GlobalShaderCache().release( "$PIVOT" );
|
||||
GlobalShaderCache().release( "$BIGPOINT" );
|
||||
|
|
@ -7805,7 +7962,11 @@ AABB RadiantSelectionSystem::getSelectionAABB() const {
|
|||
|
||||
void RadiantSelectionSystem::renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
|
||||
//if(view->TestPoint(m_object_pivot))
|
||||
if ( !nothingSelected() || ManipulatorMode() == eClip || ManipulatorMode() == eBuild || ManipulatorMode() == eUV ) {
|
||||
if ( !nothingSelected()
|
||||
|| ManipulatorMode() == eClip
|
||||
|| ManipulatorMode() == eBuild
|
||||
|| ManipulatorMode() == eUV
|
||||
|| ManipulatorMode() == eDrag ) {
|
||||
renderer.Highlight( Renderer::ePrimitive, false );
|
||||
renderer.Highlight( Renderer::eFace, false );
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user