store winding points in double precision

This commit is contained in:
Garux 2021-11-23 14:48:00 +03:00
parent af14a811af
commit 6c129e546f
13 changed files with 105 additions and 123 deletions

View File

@ -208,7 +208,7 @@ bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode m
{ {
std::multimap<std::string, std::string> brushMaterials; std::multimap<std::string, std::string> brushMaterials;
std::vector<Vector3> vertices; // unique vertices list for welding std::vector<DoubleVector3> vertices; // unique vertices list for welding
// submesh starts here // submesh starts here
if ( objs ) { if ( objs ) {
@ -238,9 +238,9 @@ bool ExportDataAsWavefront::WriteToFile( const std::string& path, collapsemode m
--i; --i;
++texcoord_count; ++texcoord_count;
std::size_t vertexN = 0; // vertex index to use, 0 is special value = no vertex to weld to found std::size_t vertexN = 0; // vertex index to use, 0 is special value = no vertex to weld to found
const Vector3& vertex = w[i].vertex; const DoubleVector3& vertex = w[i].vertex;
if( weld ){ if( weld ){
auto found = std::find_if( vertices.begin(), vertices.end(), [&vertex]( const Vector3& othervertex ){ auto found = std::find_if( vertices.begin(), vertices.end(), [&vertex]( const DoubleVector3& othervertex ){
return Edge_isDegenerate( vertex, othervertex ); return Edge_isDegenerate( vertex, othervertex );
} ); } );
if( found == vertices.end() ){ // unique vertex, add to the list if( found == vertices.end() ){ // unique vertex, add to the list

View File

@ -52,7 +52,7 @@ public:
virtual void gatherComponentsHighlight( std::vector<std::vector<Vector3>>& polygons, SelectionIntersection& intersection, SelectionTest& test, SelectionSystem::EComponentMode mode ) const = 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; typedef std::function<void( const DoubleVector3& )> Vector3Callback;
class ComponentEditable class ComponentEditable
{ {

View File

@ -144,7 +144,7 @@ static void InitPakFile( ArchiveModules& archiveModules, const char *filename ){
} }
inline void pathlist_append_unique( StrList& pathlist, CopiedString path ){ inline void pathlist_append_unique( StrList& pathlist, CopiedString path ){
if( pathlist.cend() == std::find_if( pathlist.cbegin(), pathlist.cend(), if( std::none_of( pathlist.cbegin(), pathlist.cend(),
[&path]( const CopiedString& str ){ return path_compare( str.c_str(), path.c_str() ) == 0; } ) ) [&path]( const CopiedString& str ){ return path_compare( str.c_str(), path.c_str() ) == 0; } ) )
pathlist.emplace_back( std::move( path ) ); pathlist.emplace_back( std::move( path ) );
} }

View File

@ -422,11 +422,7 @@ public:
m_planes.push_back( plane ); m_planes.push_back( plane );
} }
iterator find( const Plane3& plane ){ iterator find( const Plane3& plane ){
iterator i = begin(); return std::find_if( begin(), end(), [&plane]( const VertexModePlane& pla ){ return plane3_equal( plane, pla.m_plane ); } );
for( ; i != end(); ++i )
if( plane3_equal( plane, i->m_plane ) )
break;
return i;
} }
const_iterator begin() const { const_iterator begin() const {
return m_planes.begin(); return m_planes.begin();
@ -446,15 +442,13 @@ public:
}; };
const Face* vertex_mode_find_common_face( const Brush::VertexModeVertex& v1, const Brush::VertexModeVertex& v2, const Brush::VertexModeVertex& v3 ){ const Face* vertex_mode_find_common_face( const Brush::VertexModeVertex& v1, const Brush::VertexModeVertex& v2, const Brush::VertexModeVertex& v3 ){
const Face* face = 0; for( const Face* face : v1.m_faces ){
for( const auto& i : v1.m_faces ){ if( std::find( v2.m_faces.begin(), v2.m_faces.end(), face ) != v2.m_faces.end()
if( std::find( v2.m_faces.begin(), v2.m_faces.end(), i ) != v2.m_faces.end() && std::find( v3.m_faces.begin(), v3.m_faces.end(), face ) != v3.m_faces.end() ){
&& std::find( v3.m_faces.begin(), v3.m_faces.end(), i ) != v3.m_faces.end() ){ return face;
face = i;
break;
} }
} }
return face; return nullptr;
} }
#include "quickhull/QuickHull.hpp" #include "quickhull/QuickHull.hpp"
@ -463,9 +457,9 @@ void Brush::vertexModeBuildHull( bool allTransformed /*= false*/ ){
std::vector<quickhull::Vector3<double>> pointCloud; std::vector<quickhull::Vector3<double>> pointCloud;
pointCloud.reserve( m_vertexModeVertices.size() ); pointCloud.reserve( m_vertexModeVertices.size() );
for( auto& i : m_vertexModeVertices ){ for( auto& i : m_vertexModeVertices ){
pointCloud.push_back( quickhull::Vector3<double>( static_cast<double>( i.m_vertexTransformed.x() ), pointCloud.push_back( quickhull::Vector3<double>( i.m_vertexTransformed.x(),
static_cast<double>( i.m_vertexTransformed.y() ), i.m_vertexTransformed.y(),
static_cast<double>( i.m_vertexTransformed.z() ) ) ); i.m_vertexTransformed.z() ) );
} }
auto hull = quickhull.getConvexHull( pointCloud, true, true ); auto hull = quickhull.getConvexHull( pointCloud, true, true );
const auto& indexBuffer = hull.getIndexBuffer(); const auto& indexBuffer = hull.getIndexBuffer();

View File

@ -79,12 +79,12 @@ inline bool texdef_sane( const texdef_t& texdef ){
} }
inline void Winding_DrawWireframe( const Winding& winding ){ inline void Winding_DrawWireframe( const Winding& winding ){
glVertexPointer( 3, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->vertex ); glVertexPointer( 3, GL_DOUBLE, sizeof( WindingVertex ), &winding.points.data()->vertex );
glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) ); glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) );
} }
inline void Winding_Draw( const Winding& winding, const Vector3& normal, RenderStateFlags state ){ inline void Winding_Draw( const Winding& winding, const Vector3& normal, RenderStateFlags state ){
glVertexPointer( 3, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->vertex ); glVertexPointer( 3, GL_DOUBLE, sizeof( WindingVertex ), &winding.points.data()->vertex );
Vector3 normals[c_brush_maxFaces]; Vector3 normals[c_brush_maxFaces];
@ -823,7 +823,7 @@ public:
updateSource(); updateSource();
} }
} }
void copy( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){ void copy( const DoubleVector3& p0, const DoubleVector3& p1, const DoubleVector3& p2 ){
if ( !isDoom3Plane() ) { if ( !isDoom3Plane() ) {
m_planepts[0] = p0; m_planepts[0] = p0;
m_planepts[1] = p1; m_planepts[1] = p1;
@ -980,14 +980,14 @@ public:
m_undoable_observer( 0 ), m_undoable_observer( 0 ),
m_map( 0 ){ m_map( 0 ){
m_shader.attach( *this ); m_shader.attach( *this );
m_plane.copy( Vector3( 0, 0, 0 ), Vector3( 64, 0, 0 ), Vector3( 0, 64, 0 ) ); m_plane.copy( DoubleVector3( 0, 0, 0 ), DoubleVector3( 64, 0, 0 ), DoubleVector3( 0, 64, 0 ) );
m_texdef.setBasis( m_plane.plane3().normal() ); m_texdef.setBasis( m_plane.plane3().normal() );
planeChanged(); planeChanged();
} }
Face( Face(
const Vector3& p0, const DoubleVector3& p0,
const Vector3& p1, const DoubleVector3& p1,
const Vector3& p2, const DoubleVector3& p2,
const char* shader, const char* shader,
const TextureProjection& projection, const TextureProjection& projection,
FaceObserver* observer FaceObserver* observer
@ -1541,7 +1541,7 @@ public:
class SelectableVertex class SelectableVertex
{ {
public: public:
Vector3 getVertex() const { DoubleVector3 getVertex() const {
return getFace().getWinding()[m_faceVertex.getVertex()].vertex; return getFace().getWinding()[m_faceVertex.getVertex()].vertex;
} }
@ -1930,11 +1930,11 @@ public:
class VertexModeVertex class VertexModeVertex
{ {
public: public:
const Vector3 m_vertex; const DoubleVector3 m_vertex;
Vector3 m_vertexTransformed; DoubleVector3 m_vertexTransformed;
const bool m_selected; const bool m_selected;
std::vector<const Face*> m_faces; std::vector<const Face*> m_faces;
VertexModeVertex( const Vector3& vertex, const bool selected ) : m_vertex( vertex ), m_vertexTransformed( vertex ), m_selected( selected ) { VertexModeVertex( const DoubleVector3& vertex, const bool selected ) : m_vertex( vertex ), m_vertexTransformed( vertex ), m_selected( selected ) {
} }
}; };
typedef std::vector<VertexModeVertex> VertexModeVertices; typedef std::vector<VertexModeVertex> VertexModeVertices;
@ -2030,7 +2030,7 @@ public:
} }
/// \brief Appends a new face constructed from the parameters to the end of the face list. /// \brief Appends a new face constructed from the parameters to the end of the face list.
Face* addPlane( const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, const TextureProjection& projection ){ Face* addPlane( const DoubleVector3& p0, const DoubleVector3& p1, const DoubleVector3& p2, const char* shader, const TextureProjection& projection ){
if ( m_faces.size() == c_brush_maxFaces ) { if ( m_faces.size() == c_brush_maxFaces ) {
return 0; return 0;
} }
@ -3357,7 +3357,7 @@ public:
} }
while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() ); while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
} }
bool vertex_select( const Vector3& vertex ){ bool vertex_select( const DoubleVector3& vertex ){
if( vector3_length_squared( vertex - m_vertex->getVertex() ) < ( 0.1 * 0.1 ) ){ if( vector3_length_squared( vertex - m_vertex->getVertex() ) < ( 0.1 * 0.1 ) ){
setSelected( true ); setSelected( true );
return true; return true;
@ -4036,7 +4036,7 @@ public:
v.pop_back(); v.pop_back();
} }
std::vector<bool> ok( v.size(), true ); std::vector<bool> ok( v.size(), true );
gatherSelectedComponents( [&]( const Vector3 & value ) { gatherSelectedComponents( [&]( const DoubleVector3 & value ) {
for( std::size_t i = 0; i < v.size(); ++i ) for( std::size_t i = 0; i < v.size(); ++i )
if( vector3_length_squared( v[i].m_vertex - value ) < 0.05 * 0.05 ) if( vector3_length_squared( v[i].m_vertex - value ) < 0.05 * 0.05 )
ok[i] = false; ok[i] = false;

View File

@ -305,17 +305,17 @@ void Texdef_EmitTextureCoordinates( const TextureProjection& projection, std::si
matrix4_multiply_by_matrix4( local2tex, xyz2st ); matrix4_multiply_by_matrix4( local2tex, xyz2st );
} }
Vector3 tangent( vector3_normalised( vector4_to_vector3( matrix4_transposed( local2tex ).x() ) ) ); const Vector3 tangent( vector3_normalised( vector4_to_vector3( matrix4_transposed( local2tex ).x() ) ) );
Vector3 bitangent( vector3_normalised( vector4_to_vector3( matrix4_transposed( local2tex ).y() ) ) ); const Vector3 bitangent( vector3_normalised( vector4_to_vector3( matrix4_transposed( local2tex ).y() ) ) );
matrix4_multiply_by_matrix4( local2tex, localToWorld ); matrix4_multiply_by_matrix4( local2tex, localToWorld );
for ( Winding::iterator i = w.begin(); i != w.end(); ++i ) for ( WindingVertex& v : w )
{ {
( *i ).texcoord = matrix4_transformed_point( local2tex, ( *i ).vertex ).vec2(); v.texcoord = matrix4_transformed_point( local2tex, v.vertex ).vec2();
( *i ).tangent = tangent; v.tangent = tangent;
( *i ).bitangent = bitangent; v.bitangent = bitangent;
} }
} }

View File

@ -400,7 +400,7 @@ void Brush_ConstructIcosahedron( Brush& brush, const AABB& bounds, std::size_t s
} }
const Plane3 plane = plane3_for_points( p ); const Plane3 plane = plane3_for_points( p );
if( plane3_valid( plane ) ){ if( plane3_valid( plane ) ){
if( std::find_if( planes.begin(), planes.end(), [&plane]( const Plane3& pla ){ return plane3_equal( plane, pla ); } ) == planes.end() ){ if( std::none_of( planes.begin(), planes.end(), [&plane]( const Plane3& pla ){ return plane3_equal( plane, pla ); } ) ){
planes.push_back( plane ); planes.push_back( plane );
brush.addPlane( p[0] * radius + mid, p[1] * radius + mid, p[2] * radius + mid, shader, projection ); brush.addPlane( p[0] * radius + mid, p[1] * radius + mid, p[2] * radius + mid, shader, projection );
} }

View File

@ -243,7 +243,7 @@ void brush_extrudeDiag( const Brush& brush0, const Brush& brush2, brush_vector_t
const auto addSidePlanes = [&m_out, shader, &projection]( const Winding& winding0, const Winding& winding2, const DoubleVector3 normal, const bool swap ){ const auto addSidePlanes = [&m_out, shader, &projection]( const Winding& winding0, const Winding& winding2, const DoubleVector3 normal, const bool swap ){
for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){ for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){
const std::size_t next = Winding_next( winding0, index0 ); const std::size_t next = Winding_next( winding0, index0 );
Vector3 BestPoint; DoubleVector3 BestPoint;
double bestdot = -1; double bestdot = -1;
for( std::size_t index2 = 0; index2 < winding2.numpoints; ++index2 ){ for( std::size_t index2 = 0; index2 < winding2.numpoints; ++index2 ){
const double dot = vector3_dot( const double dot = vector3_dot(
@ -275,7 +275,7 @@ void brush_extrudeDiag( const Brush& brush0, const Brush& brush2, brush_vector_t
const Winding& winding0 = face0.getWinding(); const Winding& winding0 = face0.getWinding();
for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){ for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){
const std::size_t next = Winding_next( winding0, index0 ); const std::size_t next = Winding_next( winding0, index0 );
Vector3 BestPoint; DoubleVector3 BestPoint;
double bestdist = 999999; double bestdist = 999999;
for( const Face* f : brush2 ) { for( const Face* f : brush2 ) {
const Winding& winding2 = f->getWinding(); const Winding& winding2 = f->getWinding();
@ -966,19 +966,16 @@ void CSG_Merge(){
class MergeVertices class MergeVertices
{ {
typedef std::vector<Vector3> Vertices; typedef std::vector<DoubleVector3> Vertices;
Vertices m_vertices; Vertices m_vertices;
public: public:
typedef Vertices::const_iterator const_iterator; typedef Vertices::const_iterator const_iterator;
void insert( const Vector3& vertex ){ void insert( const DoubleVector3& vertex ){
if( !contains( vertex ) ) if( !contains( vertex ) )
m_vertices.push_back( vertex ); m_vertices.push_back( vertex );
} }
bool contains( const Vector3& vertex ) const { bool contains( const DoubleVector3& vertex ) const {
for( const_iterator i = begin(); i != end(); ++i ) return std::any_of( begin(), end(), [&vertex]( const DoubleVector3& v ){ return Edge_isDegenerate( vertex, v ); } );
if( Edge_isDegenerate( vertex, *i ) )
return true;
return false;
} }
const_iterator begin() const { const_iterator begin() const {
return m_vertices.begin(); return m_vertices.begin();
@ -989,13 +986,13 @@ public:
std::size_t size() const { std::size_t size() const {
return m_vertices.size(); return m_vertices.size();
} }
const Vector3& operator[]( std::size_t i ) const { const DoubleVector3& operator[]( std::size_t i ) const {
return m_vertices[i]; return m_vertices[i];
} }
brushsplit_t classify_plane( const Plane3& plane ) const { brushsplit_t classify_plane( const Plane3& plane ) const {
brushsplit_t split; brushsplit_t split;
for( const_iterator i = begin(); i != end(); ++i ){ for( const DoubleVector3& vertex : m_vertices ){
WindingVertex_ClassifyPlane( ( *i ), plane, split ); WindingVertex_ClassifyPlane( vertex, plane, split );
if( ( split.counts[ePlaneFront] != 0 ) && ( split.counts[ePlaneBack] != 0 ) ) // optimized to break, if plane is inside if( ( split.counts[ePlaneFront] != 0 ) && ( split.counts[ePlaneBack] != 0 ) ) // optimized to break, if plane is inside
break; break;
} }
@ -1009,7 +1006,7 @@ class Scene_gatherSelectedComponents : public scene::Graph::Walker
const Vector3Callback m_callback; const Vector3Callback m_callback;
public: public:
Scene_gatherSelectedComponents( MergeVertices& mergeVertices ) Scene_gatherSelectedComponents( MergeVertices& mergeVertices )
: m_mergeVertices( mergeVertices ), m_callback( [this]( const Vector3& value ){ m_mergeVertices.insert( value ); } ){ : m_mergeVertices( mergeVertices ), m_callback( [this]( const DoubleVector3& value ){ m_mergeVertices.insert( value ); } ){
} }
bool pre( const scene::Path& path, scene::Instance& instance ) const { bool pre( const scene::Path& path, scene::Instance& instance ) const {
if ( path.top().get().visible() ) { if ( path.top().get().visible() ) {
@ -1023,17 +1020,14 @@ public:
} }
}; };
class MergePlane struct MergePlane
{ {
public: const Plane3 m_plane;
Plane3 m_plane; const Face *const m_face;
const Face* m_face; const DoubleVector3 m_verts[3];
Vector3 m_v1;
Vector3 m_v2;
Vector3 m_v3;
MergePlane( const Plane3& plane, const Face* face ) : m_plane( plane ), m_face( face ){ MergePlane( const Plane3& plane, const Face* face ) : m_plane( plane ), m_face( face ){
} }
MergePlane( const Plane3& plane, const Vector3& v1, const Vector3& v2, const Vector3& v3 ) : m_plane( plane ), m_face( 0 ), m_v1( v1 ), m_v2( v2 ), m_v3( v3 ){ MergePlane( const Plane3& plane, const DoubleVector3 verts[3] ) : m_plane( plane ), m_face( 0 ), m_verts{ verts[0], verts[1], verts[2] } {
} }
}; };
@ -1044,10 +1038,8 @@ class MergePlanes
public: public:
typedef Planes::const_iterator const_iterator; typedef Planes::const_iterator const_iterator;
void insert( const MergePlane& plane ){ void insert( const MergePlane& plane ){
for( const_iterator i = begin(); i != end(); ++i ) if( std::none_of( begin(), end(), [&plane]( const MergePlane& pla ){ return plane3_equal( plane.m_plane, pla.m_plane ); } ) )
if( plane3_equal( plane.m_plane, i->m_plane ) ) m_planes.push_back( plane );
return;
m_planes.push_back( plane );
} }
const_iterator begin() const { const_iterator begin() const {
return m_planes.begin(); return m_planes.begin();
@ -1086,22 +1078,20 @@ void CSG_build_hull( const MergeVertices& mergeVertices, MergePlanes& mergePlane
quickhull::QuickHull<double> quickhull; quickhull::QuickHull<double> quickhull;
std::vector<quickhull::Vector3<double>> pointCloud; std::vector<quickhull::Vector3<double>> pointCloud;
pointCloud.reserve( mergeVertices.size() ); pointCloud.reserve( mergeVertices.size() );
for( std::size_t i = 0; i < mergeVertices.size(); ++i ){ for( const DoubleVector3& v : mergeVertices ){
pointCloud.push_back( quickhull::Vector3<double>( static_cast<double>( mergeVertices[i].x() ), pointCloud.push_back( quickhull::Vector3<double>( v.x(), v.y(), v.z() ) );
static_cast<double>( mergeVertices[i].y() ),
static_cast<double>( mergeVertices[i].z() ) ) );
} }
auto hull = quickhull.getConvexHull( pointCloud, true, true ); auto hull = quickhull.getConvexHull( pointCloud, true, true );
const auto& indexBuffer = hull.getIndexBuffer(); const auto& indexBuffer = hull.getIndexBuffer();
const size_t triangleCount = indexBuffer.size() / 3; const size_t triangleCount = indexBuffer.size() / 3;
for( size_t i = 0; i < triangleCount; ++i ) { for( size_t i = 0; i < triangleCount; ++i ) {
Vector3 p[3]; DoubleVector3 points[3];
for( size_t j = 0; j < 3; ++j ){ for( size_t j = 0; j < 3; ++j ){
p[j] = mergeVertices[indexBuffer[i * 3 + j]]; points[j] = mergeVertices[indexBuffer[i * 3 + j]];
} }
const Plane3 plane = plane3_for_points( p[0], p[1], p[2] ); const Plane3 plane = plane3_for_points( points );
if( plane3_valid( plane ) ){ if( plane3_valid( plane ) ){
mergePlanes.insert( MergePlane( plane, p[0], p[1], p[2] ) ); mergePlanes.insert( MergePlane( plane, points ) );
} }
} }
} }
@ -1120,13 +1110,11 @@ void CSG_WrapMerge( const ClipperPoints& clipperPoints ){
MergeVertices mergeVertices; MergeVertices mergeVertices;
/* gather unique vertices */ /* gather unique vertices */
for ( brush_vector_t::const_iterator b = selected_brushes.begin(); b != selected_brushes.end(); ++b ) for ( const Brush *brush : selected_brushes )
for ( Brush::const_iterator f = ( *b )->begin(); f != ( *b )->end(); ++f ) for ( const FaceSmartPointer& face : *brush )
if ( ( *f )->contributes() ){ if ( face->contributes() )
const Winding& winding = ( *f )->getWinding(); for ( const WindingVertex& v : face->getWinding() )
for ( std::size_t w = 0; w != winding.numpoints; ++w ) mergeVertices.insert( v.vertex );
mergeVertices.insert( winding[w].vertex );
}
GlobalSceneGraph().traverse( Scene_gatherSelectedComponents( mergeVertices ) ); GlobalSceneGraph().traverse( Scene_gatherSelectedComponents( mergeVertices ) );
@ -1141,15 +1129,13 @@ void CSG_WrapMerge( const ClipperPoints& clipperPoints ){
MergePlanes mergePlanes; MergePlanes mergePlanes;
/* gather unique && worthy planes */ /* gather unique && worthy planes */
for ( brush_vector_t::const_iterator b = selected_brushes.begin(); b != selected_brushes.end(); ++b ) for ( const Brush *brush : selected_brushes )
for ( Brush::const_iterator f = ( *b )->begin(); f != ( *b )->end(); ++f ){ for ( const FaceSmartPointer& face : *brush )
const Face& face = *( *f ); if ( face->contributes() ){
if ( face.contributes() ){ const brushsplit_t split = mergeVertices.classify_plane( face->getPlane().plane3() );
const brushsplit_t split = mergeVertices.classify_plane( face.getPlane().plane3() );
if( ( split.counts[ePlaneFront] == 0 ) != ( split.counts[ePlaneBack] == 0 ) ) if( ( split.counts[ePlaneFront] == 0 ) != ( split.counts[ePlaneBack] == 0 ) )
mergePlanes.insert( MergePlane( face.getPlane().plane3(), &face ) ); mergePlanes.insert( MergePlane( face->getPlane().plane3(), face.get() ) );
} }
}
CSG_build_hull( mergeVertices, mergePlanes ); CSG_build_hull( mergeVertices, mergePlanes );
@ -1172,12 +1158,12 @@ void CSG_WrapMerge( const ClipperPoints& clipperPoints ){
const char* shader = TextureBrowser_GetSelectedShader(); const char* shader = TextureBrowser_GetSelectedShader();
TextureProjection projection; TextureProjection projection;
TexDef_Construct_Default( projection ); TexDef_Construct_Default( projection );
for( MergePlanes::const_iterator i = mergePlanes.begin(); i != mergePlanes.end(); ++i ){ for( const MergePlane& p : mergePlanes ){
if( i->m_face ) if( p.m_face )
brush->addFace( *( i->m_face ) ); brush->addFace( *( p.m_face ) );
else else
brush->addPlane( i->m_v1, i->m_v2, i->m_v3, shader, projection ); brush->addPlane( p.m_verts[0], p.m_verts[1], p.m_verts[2], shader, projection );
// globalOutputStream() << i->m_plane.normal() << " " << i->m_plane.dist() << " i->m_plane\n"; // globalOutputStream() << p.m_plane.normal() << " " << p.m_plane.dist() << " p.m_plane\n";
} }
brush->removeEmptyFaces(); brush->removeEmptyFaces();
} }

View File

@ -1034,7 +1034,7 @@ private:
const auto addSidePlanes = [&outBrush, shader, &projection]( const Winding& winding0, const Winding& winding2, const DoubleVector3 normal, const bool swap ){ const auto addSidePlanes = [&outBrush, shader, &projection]( const Winding& winding0, const Winding& winding2, const DoubleVector3 normal, const bool swap ){
for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){ for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){
const std::size_t next = Winding_next( winding0, index0 ); const std::size_t next = Winding_next( winding0, index0 );
Vector3 BestPoint; DoubleVector3 BestPoint;
double bestdot = -1; double bestdot = -1;
for( std::size_t index2 = 0; index2 < winding2.numpoints; ++index2 ){ for( std::size_t index2 = 0; index2 < winding2.numpoints; ++index2 ){
const double dot = vector3_dot( const double dot = vector3_dot(
@ -1066,7 +1066,7 @@ private:
const auto addSidePlanes = [&outBrush, shader, &projection]( const Winding& winding0, const Brush& brush2, const Plane3 plane, const bool swap ){ const auto addSidePlanes = [&outBrush, shader, &projection]( const Winding& winding0, const Brush& brush2, const Plane3 plane, const bool swap ){
for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){ for( std::size_t index0 = 0; index0 < winding0.numpoints; ++index0 ){
const std::size_t next = Winding_next( winding0, index0 ); const std::size_t next = Winding_next( winding0, index0 );
Vector3 BestPoint; DoubleVector3 BestPoint;
double bestdist = 999999; double bestdist = 999999;
for( const Face* f : brush2 ) { for( const Face* f : brush2 ) {
const Winding& winding2 = f->getWinding(); const Winding& winding2 = f->getWinding();
@ -3170,9 +3170,9 @@ public:
BestPoint( BestPoint(
matrix4_clip_triangle( matrix4_clip_triangle(
m_local2view, m_local2view,
reinterpret_cast<const Vector3&>( vertices[0] ), reinterpret_cast<const DoubleVector3&>( vertices[0] ),
reinterpret_cast<const Vector3&>( vertices[i + 1] ), reinterpret_cast<const DoubleVector3&>( vertices[i + 1] ),
reinterpret_cast<const Vector3&>( vertices[i + 2] ), reinterpret_cast<const DoubleVector3&>( vertices[i + 2] ),
clipped clipped
), ),
clipped, clipped,
@ -4100,21 +4100,23 @@ Vector3 testSelected_scene_snapped_point( const SelectionVolume& test, ClipperSe
float bestDist = FLT_MAX; float bestDist = FLT_MAX;
Vector3 wannabePoint; Vector3 wannabePoint;
for ( Winding::const_iterator prev = face.getWinding().end() - 1, curr = face.getWinding().begin(); curr != face.getWinding().end(); prev = curr, ++curr ){ for ( Winding::const_iterator prev = face.getWinding().end() - 1, curr = face.getWinding().begin(); curr != face.getWinding().end(); prev = curr, ++curr ){
const Vector3 v1( prev->vertex );
const Vector3 v2( curr->vertex );
{ /* try vertices */ { /* try vertices */
const float dist = vector3_length_squared( ( *curr ).vertex - point ); const float dist = vector3_length_squared( v2 - point );
if( dist < bestDist ){ if( dist < bestDist ){
wannabePoint = ( *curr ).vertex; wannabePoint = v2;
bestDist = dist; bestDist = dist;
} }
} }
{ /* try edges */ { /* try edges */
Vector3 edgePoint = line_closest_point( Line( ( *prev ).vertex, ( *curr ).vertex ), point ); Vector3 edgePoint = line_closest_point( Line( v1, v2 ), point );
if( edgePoint != ( *prev ).vertex && edgePoint != ( *curr ).vertex ){ if( edgePoint != v1 && edgePoint != v2 ){
const Vector3 edgedir = vector3_normalised( ( *curr ).vertex - ( *prev ).vertex ); const Vector3 edgedir = vector3_normalised( v2 - v1 );
const std::size_t maxi = vector3_max_abs_component_index( edgedir ); const std::size_t maxi = vector3_max_abs_component_index( edgedir );
// ( *prev ).vertex[maxi] + edgedir[maxi] * coef = float_snapped( point[maxi], GetSnapGridSize() ) // v1[maxi] + edgedir[maxi] * coef = float_snapped( point[maxi], GetSnapGridSize() )
const float coef = ( float_snapped( point[maxi], GetSnapGridSize() ) - ( *prev ).vertex[maxi] ) / edgedir[maxi]; const float coef = ( float_snapped( point[maxi], GetSnapGridSize() ) - v1[maxi] ) / edgedir[maxi];
edgePoint = ( *prev ).vertex + edgedir * coef; edgePoint = v1 + edgedir * coef;
const float dist = vector3_length_squared( edgePoint - point ); const float dist = vector3_length_squared( edgePoint - point );
if( dist < bestDist ){ if( dist < bestDist ){
wannabePoint = edgePoint; wannabePoint = edgePoint;

View File

@ -1715,7 +1715,7 @@ static std::vector<const PatchControl*> Patch_getClosestTriangle( const PatchDat
/* try patchControls-on-edgeLine */ /* try patchControls-on-edgeLine */
for ( std::size_t i = w.numpoints - 1, j = 0; j < w.numpoints && ret.empty(); i = j, ++j ) for ( std::size_t i = w.numpoints - 1, j = 0; j < w.numpoints && ret.empty(); i = j, ++j )
{ {
const auto ray_close = [eps, ray = ray_for_points( DoubleVector3( w[i].vertex ), DoubleVector3( w[j].vertex ) )]( const PatchControl& p ){ const auto ray_close = [eps, ray = ray_for_points( w[i].vertex, w[j].vertex )]( const PatchControl& p ){
return ray_squared_distance_to_point( ray, p.m_vertex ) < eps; return ray_squared_distance_to_point( ray, p.m_vertex ) < eps;
}; };
find_triangle( ray_close ); find_triangle( ray_close );

View File

@ -253,7 +253,7 @@ brushsplit_t Winding_ClassifyPlane( const Winding& winding, const Plane3& plane
return split; return split;
} }
void WindingVertex_ClassifyPlane( const Vector3& vertex, const Plane3& plane, brushsplit_t& split ){ void WindingVertex_ClassifyPlane( const DoubleVector3& vertex, const Plane3& plane, brushsplit_t& split ){
++split.counts[Winding_ClassifyDistance( plane3_distance_to_point( plane, vertex ), ON_EPSILON )]; ++split.counts[Winding_ClassifyDistance( plane3_distance_to_point( plane, vertex ), ON_EPSILON )];
} }
@ -339,7 +339,7 @@ std::size_t Winding_Opposite( const Winding& winding, const std::size_t index, c
double dist_best = 0; double dist_best = 0;
std::size_t index_best = c_brush_maxFaces; std::size_t index_best = c_brush_maxFaces;
Ray edge( ray_for_points( winding[index].vertex, winding[other].vertex ) ); const DoubleRay edge( ray_for_points( winding[index].vertex, winding[other].vertex ) );
for ( std::size_t i = 0; i < winding.numpoints; ++i ) for ( std::size_t i = 0; i < winding.numpoints; ++i )
{ {
@ -347,7 +347,7 @@ std::size_t Winding_Opposite( const Winding& winding, const std::size_t index, c
continue; continue;
} }
double dist_squared = ray_squared_distance_to_point( edge, winding[i].vertex ); const double dist_squared = ray_squared_distance_to_point( edge, winding[i].vertex );
if ( dist_squared > dist_best ) { if ( dist_squared > dist_best ) {
dist_best = dist_squared; dist_best = dist_squared;
@ -368,20 +368,20 @@ void Winding_Centroid( const Winding& winding, const Plane3& plane, Vector3& cen
const indexremap_t remap = indexremap_for_projectionaxis( axis ); const indexremap_t remap = indexremap_for_projectionaxis( axis );
for ( std::size_t i = winding.numpoints - 1, j = 0; j < winding.numpoints; i = j, ++j ) for ( std::size_t i = winding.numpoints - 1, j = 0; j < winding.numpoints; i = j, ++j )
{ {
const double ai = static_cast<double>( winding[i].vertex[remap.x] ) * winding[j].vertex[remap.y] - static_cast<double>( winding[j].vertex[remap.x] ) * winding[i].vertex[remap.y]; const double ai = winding[i].vertex[remap.x] * winding[j].vertex[remap.y] - winding[j].vertex[remap.x] * winding[i].vertex[remap.y];
area2 += ai; area2 += ai;
x_sum += ( static_cast<double>( winding[j].vertex[remap.x] ) + winding[i].vertex[remap.x] ) * ai; x_sum += ( winding[j].vertex[remap.x] + winding[i].vertex[remap.x] ) * ai;
y_sum += ( static_cast<double>( winding[j].vertex[remap.y] ) + winding[i].vertex[remap.y] ) * ai; y_sum += ( winding[j].vertex[remap.y] + winding[i].vertex[remap.y] ) * ai;
} }
centroid[remap.x] = static_cast<float>( x_sum / ( 3 * area2 ) ); centroid[remap.x] = x_sum / ( 3 * area2 );
centroid[remap.y] = static_cast<float>( y_sum / ( 3 * area2 ) ); centroid[remap.y] = y_sum / ( 3 * area2 );
{ {
Ray ray( Vector3( 0, 0, 0 ), Vector3( 0, 0, 0 ) ); Ray ray( Vector3( 0, 0, 0 ), Vector3( 0, 0, 0 ) );
ray.origin[remap.x] = centroid[remap.x]; ray.origin[remap.x] = centroid[remap.x];
ray.origin[remap.y] = centroid[remap.y]; ray.origin[remap.y] = centroid[remap.y];
ray.direction[remap.z] = 1; ray.direction[remap.z] = 1;
centroid[remap.z] = static_cast<float>( ray_distance_to_plane( ray, plane ) ); centroid[remap.z] = ray_distance_to_plane( ray, plane );
} }
// windingTestInfinity(); // windingTestInfinity();
} }

View File

@ -85,7 +85,7 @@ const std::size_t c_brush_maxFaces = 1024;
class WindingVertex class WindingVertex
{ {
public: public:
Vector3 vertex; DoubleVector3 vertex;
Vector2 texcoord; Vector2 texcoord;
Vector3 tangent; Vector3 tangent;
Vector3 bitangent; Vector3 bitangent;
@ -210,9 +210,9 @@ inline void Winding_forFixedWinding( Winding& winding, const FixedWinding& fixed
winding.numpoints = fixed.size(); winding.numpoints = fixed.size();
for ( std::size_t i = 0; i < fixed.size(); ++i ) for ( std::size_t i = 0; i < fixed.size(); ++i )
{ {
winding[i].vertex[0] = static_cast<float>( fixed[i].vertex[0] ); winding[i].vertex[0] = fixed[i].vertex[0];
winding[i].vertex[1] = static_cast<float>( fixed[i].vertex[1] ); winding[i].vertex[1] = fixed[i].vertex[1];
winding[i].vertex[2] = static_cast<float>( fixed[i].vertex[2] ); winding[i].vertex[2] = fixed[i].vertex[2];
winding[i].adjacent = fixed[i].adjacent; winding[i].adjacent = fixed[i].adjacent;
} }
} }
@ -232,7 +232,7 @@ void Winding_createInfinite( FixedWinding& w, const Plane3& plane, double infini
const double ON_EPSILON = 1.0 / ( 1 << 8 ); const double ON_EPSILON = 1.0 / ( 1 << 8 );
/// \brief Returns true if edge (\p x, \p y) is smaller than the epsilon used to classify winding points against a plane. /// \brief Returns true if edge (\p x, \p y) is smaller than the epsilon used to classify winding points against a plane.
inline bool Edge_isDegenerate( const Vector3& x, const Vector3& y ){ inline bool Edge_isDegenerate( const DoubleVector3& x, const DoubleVector3& y ){
return vector3_length_squared( y - x ) < ( ON_EPSILON * ON_EPSILON ); return vector3_length_squared( y - x ) < ( ON_EPSILON * ON_EPSILON );
} }
@ -255,7 +255,7 @@ struct brushsplit_t
}; };
brushsplit_t Winding_ClassifyPlane( const Winding& w, const Plane3& plane ); brushsplit_t Winding_ClassifyPlane( const Winding& w, const Plane3& plane );
void WindingVertex_ClassifyPlane( const Vector3& vertex, const Plane3& plane, brushsplit_t& split ); void WindingVertex_ClassifyPlane( const DoubleVector3& vertex, const Plane3& plane, brushsplit_t& split );
bool Winding_PlanesConcave( const Winding& w1, const Winding& w2, const Plane3& plane1, const Plane3& plane2 ); bool Winding_PlanesConcave( const Winding& w1, const Winding& w2, const Plane3& plane1, const Plane3& plane2 );
bool Winding_TestPlane( const Winding& w, const Plane3& plane, bool flipped ); bool Winding_TestPlane( const Winding& w, const Plane3& plane, bool flipped );

View File

@ -1239,7 +1239,7 @@ void SmoothMetaTriangles(){
smoothed[ j ] = true; smoothed[ j ] = true;
/* see if this normal has already been voted */ /* see if this normal has already been voted */
if( votes.end() == std::find_if( votes.begin(), votes.end(), if( std::none_of( votes.begin(), votes.end(),
[normal = verts[j]->normal]( const Vector3& vote ){ [normal = verts[j]->normal]( const Vector3& vote ){
return vector3_equal_epsilon( normal, vote, EQUAL_NORMAL_EPSILON ); return vector3_equal_epsilon( normal, vote, EQUAL_NORMAL_EPSILON );
} ) ) } ) )