diff --git a/libs/math/plane.h b/libs/math/plane.h index 3913cc56..fb1a0c48 100644 --- a/libs/math/plane.h +++ b/libs/math/plane.h @@ -125,17 +125,27 @@ inline bool plane3_valid( const Plane3& self ){ return float_equal_epsilon( vector3_dot( self.normal(), self.normal() ), 1.0, 0.01 ); } + /* + * The order of points, when looking from outside the face: + * + * 1 + * | + * | + * | + * | + * 0-----------2 + */ template inline Plane3 plane3_for_points( const BasicVector3& p0, const BasicVector3& p1, const BasicVector3& p2 ){ Plane3 self; - self.normal() = vector3_normalised( vector3_cross( vector3_subtracted( p1, p0 ), vector3_subtracted( p2, p0 ) ) ); + self.normal() = vector3_normalised( vector3_cross( vector3_subtracted( p2, p0 ), vector3_subtracted( p1, p0 ) ) ); self.dist() = vector3_dot( p0, self.normal() ); return self; } template inline Plane3 plane3_for_points( const BasicVector3 planepts[3] ){ - return plane3_for_points( planepts[2], planepts[1], planepts[0] ); + return plane3_for_points( planepts[0], planepts[1], planepts[2] ); } template diff --git a/radiant/brush.cpp b/radiant/brush.cpp index 018b4071..8b8d2779 100644 --- a/radiant/brush.cpp +++ b/radiant/brush.cpp @@ -467,7 +467,7 @@ void Brush::vertexModeBuildHull( bool allTransformed /*= false*/ ){ static_cast( i.m_vertexTransformed.y() ), static_cast( i.m_vertexTransformed.z() ) ) ); } - auto hull = quickhull.getConvexHull( pointCloud, false, true ); + auto hull = quickhull.getConvexHull( pointCloud, true, true ); const auto& indexBuffer = hull.getIndexBuffer(); const size_t triangleCount = indexBuffer.size() / 3; VertexModePlanes vertexModePlanes; @@ -490,7 +490,7 @@ void Brush::vertexModeBuildHull( bool allTransformed /*= false*/ ){ if( vector3_dot( plane.normal(), face->getPlane().plane3().normal() ) < 0 ){ //likely reversed plane transformed = true; } - vertexModePlanes.push_back( VertexModePlane( plane, face, v[0], v[2], v[1], transformed ) ); + vertexModePlanes.push_back( VertexModePlane( plane, face, v[0], v[1], v[2], transformed ) ); } else{ it->m_transformed |= transformed; diff --git a/radiant/brush.h b/radiant/brush.h index 30aca8c0..24286f25 100644 --- a/radiant/brush.h +++ b/radiant/brush.h @@ -831,7 +831,7 @@ void copy( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){ } else { - m_planeCached = plane3_for_points( p2, p1, p0 ); + m_planeCached = plane3_for_points( p0, p1, p2 ); updateSource(); } } diff --git a/radiant/csg.cpp b/radiant/csg.cpp index 8626bd53..c774a13c 100644 --- a/radiant/csg.cpp +++ b/radiant/csg.cpp @@ -747,7 +747,7 @@ void CSG_Subtract(){ class BrushSplitByPlaneSelected : public scene::Graph::Walker { const ClipperPoints m_points; -const Plane3 m_plane; +const Plane3 m_plane; /* plane to insert */ const char* m_shader; const TextureProjection& m_projection; const bool m_split; /* split or clip */ @@ -774,7 +774,7 @@ void post( const scene::Path& path, scene::Instance& instance ) const { NodeSmartReference node( ( new BrushNode() )->node() ); Brush* fragment = Node_getBrush( node ); fragment->copy( *brush ); - fragment->addPlane( m_points[0], m_points[1], m_points[2], m_shader, m_projection ); + fragment->addPlane( m_points[0], m_points[2], m_points[1], m_shader, m_projection ); fragment->removeEmptyFaces(); ASSERT_MESSAGE( !fragment->empty(), "brush left with no faces after split" ); @@ -786,13 +786,13 @@ void post( const scene::Path& path, scene::Instance& instance ) const { } } - brush->addPlane( m_points[0], m_points[2], m_points[1], m_shader, m_projection ); + brush->addPlane( m_points[0], m_points[1], m_points[2], m_shader, m_projection ); brush->removeEmptyFaces(); ASSERT_MESSAGE( !brush->empty(), "brush left with no faces after split" ); } else // the plane does not intersect this brush - if ( !m_split && split.counts[ePlaneFront] != 0 ) { + if ( !m_split && split.counts[ePlaneBack] != 0 ) { // the brush is "behind" the plane m_gj = true; Path_deleteTop( path ); @@ -1097,9 +1097,9 @@ void CSG_build_hull( const MergeVertices& mergeVertices, MergePlanes& mergePlane const brushsplit_t split = mergeVertices.classify_plane( plane ); if( ( split.counts[ePlaneFront] == 0 ) != ( split.counts[ePlaneBack] == 0 ) ){ if( split.counts[ePlaneFront] != 0 ) - mergePlanes.insert( MergePlane( plane3_flipped( plane ), *i, *j, *k ) ); + mergePlanes.insert( MergePlane( plane3_flipped( plane ), *i, *k, *j ) ); else - mergePlanes.insert( MergePlane( plane, *i, *k, *j ) ); + mergePlanes.insert( MergePlane( plane, *i, *j, *k ) ); } } } @@ -1115,7 +1115,7 @@ void CSG_build_hull( const MergeVertices& mergeVertices, MergePlanes& mergePlane static_cast( mergeVertices[i].y() ), static_cast( mergeVertices[i].z() ) ) ); } - auto hull = quickhull.getConvexHull( pointCloud, false, true ); + auto hull = quickhull.getConvexHull( pointCloud, true, true ); const auto& indexBuffer = hull.getIndexBuffer(); const size_t triangleCount = indexBuffer.size() / 3; for( size_t i = 0; i < triangleCount; ++i ) { @@ -1125,7 +1125,7 @@ void CSG_build_hull( const MergeVertices& mergeVertices, MergePlanes& mergePlane } const Plane3 plane = plane3_for_points( p[0], p[1], p[2] ); if( plane3_valid( plane ) ){ - mergePlanes.insert( MergePlane( plane, p[0], p[2], p[1] ) ); + mergePlanes.insert( MergePlane( plane, p[0], p[1], p[2] ) ); } } } diff --git a/radiant/selection.cpp b/radiant/selection.cpp index 1444113c..188c7109 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -4156,10 +4156,10 @@ public: { if( m_view->fill() ){ //3d viewdir_fixup(); - m_points[2].m_point = m_points[0].m_point + m_viewdir * vector3_length( m_points[0].m_point - m_points[1].m_point ); + m_points[2].m_point = m_points[0].m_point - m_viewdir * vector3_length( m_points[0].m_point - m_points[1].m_point ); viewdir_make_cut_worthy( plane3_for_points( m_points[0].m_point, m_points[1].m_point, m_points[2].m_point ) ); } - m_points[2].m_point = m_points[0].m_point + m_viewdir * vector3_length( m_points[0].m_point - m_points[1].m_point ); + m_points[2].m_point = m_points[0].m_point - m_viewdir * vector3_length( m_points[0].m_point - m_points[1].m_point ); } // fall through case 3: Clipper_setPlanePoints( ClipperPoints( m_points[0].m_point, m_points[1].m_point, m_points[2].m_point, npoints ) ); diff --git a/radiant/winding.h b/radiant/winding.h index 6c43c395..8599e7e9 100644 --- a/radiant/winding.h +++ b/radiant/winding.h @@ -74,8 +74,8 @@ inline indexremap_t indexremap_for_projectionaxis( const ProjectionAxis axis ){ enum PlaneClassification { - ePlaneFront = 0, - ePlaneBack = 1, + ePlaneFront = 0, //! in front of plane ---->| * + ePlaneBack = 1, //! behind the plane -*-->| ePlaneOn = 2, };