* fix alt + m1 indirect faces picking, when object is partially or fully out of camera view
refactor math functions
This commit is contained in:
parent
b9a43074f0
commit
71c63fbdc6
|
|
@ -300,7 +300,7 @@ virtual void selectPlanes( Selector& selector, SelectionTest& test, const PlaneC
|
|||
virtual void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPlanes ) = 0;
|
||||
|
||||
virtual void bestPlaneDirect( SelectionTest& test, Plane3& plane, SelectionIntersection& intersection ) = 0;
|
||||
virtual void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, const Vector3& viewer ) = 0;
|
||||
virtual void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist ) = 0;
|
||||
virtual void selectByPlane( const Plane3& plane ) = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ void bestPlaneDirect( const AABB& aabb, SelectionTest& test, Plane3& plane, Sele
|
|||
}
|
||||
m_bounds = aabb;
|
||||
}
|
||||
void bestPlaneIndirect( const AABB& aabb, SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, const Vector3& viewer, const Matrix4& rotation = g_matrix4_identity ){
|
||||
void bestPlaneIndirect( const AABB& aabb, SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, const Matrix4& rotation = g_matrix4_identity ){
|
||||
Vector3 corners[8];
|
||||
aabb_corners_oriented( aabb, rotation, corners );
|
||||
|
||||
|
|
@ -256,33 +256,32 @@ void bestPlaneIndirect( const AABB& aabb, SelectionTest& test, Plane3& plane, Ve
|
|||
3, 1,
|
||||
};
|
||||
|
||||
for( std::size_t i = 0; i < 8; ++i ){
|
||||
corners[i] = vector4_projected( matrix4_transformed_vector4( test.getVolume().GetViewMatrix(), Vector4( corners[i], 1 ) ) );
|
||||
}
|
||||
|
||||
for ( std::size_t i = 0; i < 24; ++++i ){
|
||||
const Vector3 intersection_new = line_closest_point( Line( corners[edges[i]], corners[edges[i + 1]] ), g_vector3_identity );
|
||||
const float dist_new = vector3_length_squared( intersection_new );
|
||||
if( dist_new < dist ){
|
||||
const Plane3& plane1 = planes[adjacent_planes[i]];
|
||||
const Plane3& plane2 = planes[adjacent_planes[i + 1]];
|
||||
if( ( vector3_dot( plane1.normal(), viewer ) - plane1.dist() ) <= 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( ( vector3_dot( plane2.normal(), viewer ) - plane2.dist() ) <= 0 ){
|
||||
if( aabb.extents[( ( adjacent_planes[i + 1] >> 1 ) << 1 ) / 2] == 0 ) /* select the other, if zero bound */
|
||||
plane = plane1;
|
||||
else
|
||||
Line line( corners[edges[i]], corners[edges[i + 1]] );
|
||||
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 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;
|
||||
intersection = intersection_new;
|
||||
dist = dist_new;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -363,6 +363,51 @@ inline std::size_t matrix4_clip_line( const Matrix4& self, const Vector3& p0, co
|
|||
return homogenous_clip_line( clipped );
|
||||
}
|
||||
|
||||
inline std::size_t matrix4_clip_line_by_nearplane( const Matrix4& self, Line& line ){
|
||||
Vector4 points[2] = { matrix4_transformed_vector4( self, Vector4( line.start, 1 ) ), matrix4_transformed_vector4( self, Vector4( line.end, 1 ) ) };
|
||||
const Vector4& p0 = points[0];
|
||||
const Vector4& p1 = points[1];
|
||||
|
||||
// early out
|
||||
{
|
||||
const bool passed0 = CLIP_Z_GT_W( p0 );
|
||||
const bool passed1 = CLIP_Z_GT_W( p1 );
|
||||
|
||||
if ( passed0 && passed1 ) { // both points passed all planes
|
||||
line.start = vector4_projected( p0 );
|
||||
line.end = vector4_projected( p1 );
|
||||
return 2;
|
||||
}
|
||||
|
||||
if ( !passed0 && !passed1 ) { // both points failed any one plane
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const bool index = CLIP_Z_GT_W( p0 );
|
||||
if ( index ^ CLIP_Z_GT_W( p1 ) ) {
|
||||
Vector4 clip( vector4_subtracted( p1, p0 ) );
|
||||
|
||||
double scale = ( p0[2] + p0[3] ) / ( -clip[3] - clip[2] );
|
||||
|
||||
clip[0] = static_cast<float>( p0[0] + scale * clip[0] );
|
||||
clip[1] = static_cast<float>( p0[1] + scale * clip[1] );
|
||||
clip[2] = static_cast<float>( p0[2] + scale * clip[2] );
|
||||
clip[3] = static_cast<float>( p0[3] + scale * clip[3] );
|
||||
|
||||
points[index] = clip;
|
||||
}
|
||||
else if ( index == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
line.start = vector4_projected( p0 );
|
||||
line.end = vector4_projected( p1 );
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -91,20 +91,25 @@ inline unsigned int segment_classify_plane( const Segment& segment, const Plane3
|
|||
}
|
||||
|
||||
|
||||
class Ray
|
||||
template<typename T>
|
||||
class BasicRay
|
||||
{
|
||||
public:
|
||||
Vector3 origin, direction;
|
||||
BasicVector3<T> origin, direction;
|
||||
|
||||
Ray(){
|
||||
BasicRay(){
|
||||
}
|
||||
Ray( const Vector3& origin_, const Vector3& direction_ ) :
|
||||
BasicRay( const BasicVector3<T>& origin_, const BasicVector3<T>& direction_ ) :
|
||||
origin( origin_ ), direction( direction_ ){
|
||||
}
|
||||
};
|
||||
|
||||
inline Ray ray_for_points( const Vector3& origin, const Vector3& p2 ){
|
||||
return Ray( origin, vector3_normalised( vector3_subtracted( p2, origin ) ) );
|
||||
typedef BasicRay<float> Ray;
|
||||
typedef BasicRay<double> DoubleRay;
|
||||
|
||||
template<typename T>
|
||||
inline BasicRay<T> ray_for_points( const BasicVector3<T>& origin, const BasicVector3<T>& p2 ){
|
||||
return BasicRay<T>( origin, vector3_normalised( vector3_subtracted( p2, origin ) ) );
|
||||
}
|
||||
|
||||
inline void ray_transform( Ray& ray, const Matrix4& matrix ){
|
||||
|
|
@ -132,7 +137,45 @@ inline double ray_squared_distance_to_point( const Ray& ray, const Vector3& poin
|
|||
}
|
||||
|
||||
inline double ray_distance_to_plane( const Ray& ray, const Plane3& plane ){
|
||||
return -( vector3_dot( plane.normal(), ray.origin ) - plane.dist() ) / vector3_dot( ray.direction, plane.normal() );
|
||||
return -plane3_distance_to_point( plane, ray.origin ) / vector3_dot( ray.direction, plane.normal() );
|
||||
}
|
||||
|
||||
/// \brief Returns the point at which \p ray intersects \p plane, or an undefined value if there is no intersection.
|
||||
template<typename T>
|
||||
inline BasicVector3<T> ray_intersect_plane( const BasicRay<T>& ray, const Plane3& plane ){
|
||||
return ray.origin + vector3_scaled(
|
||||
ray.direction,
|
||||
-plane3_distance_to_point( plane, ray.origin )
|
||||
/ vector3_dot( ray.direction, plane.normal() )
|
||||
);
|
||||
}
|
||||
|
||||
/// \brief Returns the infinite line that is the intersection of \p plane and \p other.
|
||||
inline DoubleRay plane3_intersect_plane3( const Plane3& plane, const Plane3& other ){
|
||||
DoubleRay line;
|
||||
line.direction = vector3_cross( plane.normal(), other.normal() );
|
||||
switch ( vector3_max_abs_component_index( line.direction ) )
|
||||
{
|
||||
case 0:
|
||||
line.origin.x() = 0;
|
||||
line.origin.y() = ( -other.dist() * plane.normal().z() - -plane.dist() * other.normal().z() ) / line.direction.x();
|
||||
line.origin.z() = ( -plane.dist() * other.normal().y() - -other.dist() * plane.normal().y() ) / line.direction.x();
|
||||
break;
|
||||
case 1:
|
||||
line.origin.x() = ( -plane.dist() * other.normal().z() - -other.dist() * plane.normal().z() ) / line.direction.y();
|
||||
line.origin.y() = 0;
|
||||
line.origin.z() = ( -other.dist() * plane.normal().x() - -plane.dist() * other.normal().x() ) / line.direction.y();
|
||||
break;
|
||||
case 2:
|
||||
line.origin.x() = ( -other.dist() * plane.normal().y() - -plane.dist() * other.normal().y() ) / line.direction.z();
|
||||
line.origin.y() = ( -plane.dist() * other.normal().x() - -other.dist() * plane.normal().x() ) / line.direction.z();
|
||||
line.origin.z() = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -138,5 +138,10 @@ inline Plane3 plane3_for_points( const BasicVector3<Element> planepts[3] ){
|
|||
return plane3_for_points( planepts[2], planepts[1], planepts[0] );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline double plane3_distance_to_point( const Plane3& plane, const BasicVector3<T>& point ){
|
||||
return vector3_dot( point, plane.normal() ) - plane.dist();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1873,10 +1873,10 @@ void bestPlaneDirect( SelectionTest& test, Plane3& plane, SelectionIntersection&
|
|||
m_dragPlanes.bestPlaneDirect( m_contained.aabb(), test, plane, intersection, rotation() );
|
||||
}
|
||||
}
|
||||
void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, const Vector3& viewer ){
|
||||
void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist ){
|
||||
if ( g_lightType == LIGHTTYPE_DOOM3 ) {
|
||||
test.BeginMesh( localToWorld() );
|
||||
m_dragPlanes.bestPlaneIndirect( m_contained.aabb(), test, plane, intersection, dist, viewer, rotation() );
|
||||
m_dragPlanes.bestPlaneIndirect( m_contained.aabb(), test, plane, intersection, dist, rotation() );
|
||||
}
|
||||
}
|
||||
void selectByPlane( const Plane3& plane ){
|
||||
|
|
|
|||
|
|
@ -1507,16 +1507,6 @@ Face& getFace() const {
|
|||
void testSelect( SelectionTest& test, SelectionIntersection& best ){
|
||||
test.TestPoint( getEdge(), best );
|
||||
}
|
||||
Vector3 bestPlaneIndirect( const SelectionTest& test ) const {
|
||||
const Winding& winding = getFace().getWinding();
|
||||
Vector3 points[2];
|
||||
points[0] = winding[m_faceVertex.getVertex()].vertex;
|
||||
points[1] = winding[Winding_next( winding, m_faceVertex.getVertex() )].vertex;
|
||||
for( std::size_t i = 0; i < 2; ++i ){
|
||||
points[i] = vector4_projected( matrix4_transformed_vector4( test.getVolume().GetViewMatrix(), Vector4( points[i], 1 ) ) );
|
||||
}
|
||||
return line_closest_point( Line( points[0], points[1] ), g_vector3_identity );
|
||||
}
|
||||
};
|
||||
|
||||
class SelectableVertex
|
||||
|
|
@ -3208,25 +3198,30 @@ void testSelect( Selector& selector, SelectionTest& test ){
|
|||
Selector_add( selector, *this, best );
|
||||
}
|
||||
}
|
||||
void bestPlaneIndirect( const SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, const Vector3& viewer ) const {
|
||||
const Vector3 intersection_new = m_edge->bestPlaneIndirect( test );
|
||||
const float dist_new = vector3_length_squared( intersection_new );
|
||||
if( dist_new < dist ){
|
||||
FaceVertexId faceVertex = m_edge->m_faceVertex;
|
||||
const Plane3& plane1 = m_faceInstances[faceVertex.getFace()].getFace().plane3();
|
||||
if( ( vector3_dot( plane1.normal(), viewer ) - plane1.dist() ) <= 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( ( vector3_dot( plane2.normal(), viewer ) - plane2.dist() ) <= 0 ){
|
||||
plane = plane2;
|
||||
|
||||
void bestPlaneIndirect( const SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist ) 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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3834,11 +3829,11 @@ void bestPlaneDirect( SelectionTest& test, Plane3& plane, SelectionIntersection&
|
|||
}
|
||||
}
|
||||
}
|
||||
void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, const Vector3& viewer ){
|
||||
void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist ){
|
||||
test.BeginMesh( localToWorld() );
|
||||
for ( EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i )
|
||||
{
|
||||
( *i ).bestPlaneIndirect( test, plane, intersection, dist, viewer );
|
||||
( *i ).bestPlaneIndirect( test, plane, intersection, dist );
|
||||
}
|
||||
}
|
||||
void selectByPlane( const Plane3& plane ){
|
||||
|
|
|
|||
|
|
@ -1629,9 +1629,9 @@ void bestPlaneDirect( SelectionTest& test, Plane3& plane, SelectionIntersection&
|
|||
test.BeginMesh( localToWorld() );
|
||||
m_dragPlanes.bestPlaneDirect( m_patch.localAABB(), test, plane, intersection );
|
||||
}
|
||||
void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, const Vector3& viewer ){
|
||||
void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist ){
|
||||
test.BeginMesh( localToWorld() );
|
||||
m_dragPlanes.bestPlaneIndirect( m_patch.localAABB(), test, plane, intersection, dist, viewer );
|
||||
m_dragPlanes.bestPlaneIndirect( m_patch.localAABB(), test, plane, intersection, dist );
|
||||
}
|
||||
void selectByPlane( const Plane3& plane ){
|
||||
m_dragPlanes.selectByPlane( m_patch.localAABB(), plane );
|
||||
|
|
|
|||
|
|
@ -69,94 +69,75 @@ struct Pivot2World
|
|||
};
|
||||
|
||||
|
||||
void point_for_device_point( Vector3& point, const Matrix4& device2object, const float x, const float y, const float z ){
|
||||
inline Vector3 point_for_device_point( const Matrix4& device2object, const float x, const float y, const float z ){
|
||||
// transform from normalised device coords to object coords
|
||||
point = vector4_projected( matrix4_transformed_vector4( device2object, Vector4( x, y, z, 1 ) ) );
|
||||
return vector4_projected( matrix4_transformed_vector4( device2object, Vector4( x, y, z, 1 ) ) );
|
||||
}
|
||||
|
||||
void ray_for_device_point( Ray& ray, const Matrix4& device2object, const float x, const float y ){
|
||||
// point at x, y, zNear
|
||||
point_for_device_point( ray.origin, device2object, x, y, -1 );
|
||||
|
||||
// point at x, y, zFar
|
||||
//point_for_device_point( ray.direction, device2object, x, y, 1 ); //sometimes is inaccurate up to negative ray direction
|
||||
point_for_device_point( ray.direction, device2object, x, y, 0 );
|
||||
|
||||
// construct ray
|
||||
vector3_subtract( ray.direction, ray.origin );
|
||||
vector3_normalise( ray.direction );
|
||||
inline Ray ray_for_device_point( const Matrix4& device2object, const float x, const float y ){
|
||||
return ray_for_points( point_for_device_point( device2object, x, y, -1 ), // point at x, y, zNear
|
||||
point_for_device_point( device2object, x, y, 0 ) // point at x, y, zFar
|
||||
//point_for_device_point( device2object, x, y, 1 ) //sometimes is inaccurate up to negative ray direction
|
||||
);
|
||||
}
|
||||
|
||||
bool sphere_intersect_ray( const Vector3& origin, float radius, const Ray& ray, Vector3& intersection ){
|
||||
intersection = vector3_subtracted( origin, ray.origin );
|
||||
inline Vector3 sphere_intersect_ray( const Vector3& origin, float radius, const Ray& ray ){
|
||||
const Vector3 intersection = vector3_subtracted( origin, ray.origin );
|
||||
const double a = vector3_dot( intersection, ray.direction );
|
||||
const double d = radius * radius - ( vector3_dot( intersection, intersection ) - a * a );
|
||||
|
||||
if ( d > 0 ) {
|
||||
intersection = vector3_added( ray.origin, vector3_scaled( ray.direction, a - sqrt( d ) ) );
|
||||
return true;
|
||||
return vector3_added( ray.origin, vector3_scaled( ray.direction, a - sqrt( d ) ) );
|
||||
// return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection = vector3_added( ray.origin, vector3_scaled( ray.direction, a ) );
|
||||
return false;
|
||||
return vector3_added( ray.origin, vector3_scaled( ray.direction, a ) );
|
||||
// return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ray_intersect_ray( const Ray& ray, const Ray& other, Vector3& intersection ){
|
||||
intersection = vector3_subtracted( ray.origin, other.origin );
|
||||
inline Vector3 ray_intersect_ray( const Ray& ray, const Ray& other ){
|
||||
const Vector3 intersection = vector3_subtracted( ray.origin, other.origin );
|
||||
//float a = 1;//vector3_dot(ray.direction, ray.direction); // always >= 0
|
||||
double dot = vector3_dot( ray.direction, other.direction );
|
||||
const double dot = vector3_dot( ray.direction, other.direction );
|
||||
//float c = 1;//vector3_dot(other.direction, other.direction); // always >= 0
|
||||
double d = vector3_dot( ray.direction, intersection );
|
||||
double e = vector3_dot( other.direction, intersection );
|
||||
double D = 1 - dot * dot; //a*c - dot*dot; // always >= 0
|
||||
const double d = vector3_dot( ray.direction, intersection );
|
||||
const double e = vector3_dot( other.direction, intersection );
|
||||
const double D = 1 - dot * dot; //a*c - dot*dot; // always >= 0
|
||||
|
||||
if ( D < 0.000001 ) {
|
||||
// the lines are almost parallel
|
||||
intersection = vector3_added( other.origin, vector3_scaled( other.direction, e ) );
|
||||
return vector3_added( other.origin, vector3_scaled( other.direction, e ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection = vector3_added( other.origin, vector3_scaled( other.direction, ( e - dot * d ) / D ) );
|
||||
return vector3_added( other.origin, vector3_scaled( other.direction, ( e - dot * d ) / D ) );
|
||||
}
|
||||
}
|
||||
|
||||
const Vector3 g_origin( 0, 0, 0 );
|
||||
const float g_radius = 64;
|
||||
|
||||
void point_on_sphere( Vector3& point, const Matrix4& device2object, const float x, const float y, const float radius = g_radius ){
|
||||
Ray ray;
|
||||
ray_for_device_point( ray, device2object, x, y );
|
||||
sphere_intersect_ray( g_origin, radius, ray, point );
|
||||
inline Vector3 point_on_sphere( const Matrix4& device2object, const float x, const float y, const float radius = g_radius ){
|
||||
return sphere_intersect_ray( g_origin,
|
||||
radius,
|
||||
ray_for_device_point( device2object, x, y ) );
|
||||
}
|
||||
|
||||
void point_on_axis( Vector3& point, const Vector3& axis, const Matrix4& device2object, const float x, const float y ){
|
||||
Ray ray;
|
||||
ray_for_device_point( ray, device2object, x, y );
|
||||
ray_intersect_ray( ray, Ray( Vector3( 0, 0, 0 ), axis ), point );
|
||||
inline Vector3 point_on_axis( const Vector3& axis, const Matrix4& device2object, const float x, const float y ){
|
||||
return ray_intersect_ray( ray_for_device_point( device2object, x, y ),
|
||||
Ray( Vector3( 0, 0, 0 ), axis ) );
|
||||
}
|
||||
|
||||
void point_on_plane( Vector3& point, const Matrix4& device2object, const float x, const float y ){
|
||||
Matrix4 object2device( matrix4_full_inverse( device2object ) );
|
||||
point = vector4_projected( matrix4_transformed_vector4( device2object, Vector4( x, y, object2device[14] / object2device[15], 1 ) ) );
|
||||
inline Vector3 point_on_plane( const Matrix4& device2object, const float x, const float y ){
|
||||
const Matrix4 object2device( matrix4_full_inverse( device2object ) );
|
||||
return vector4_projected( matrix4_transformed_vector4( device2object, Vector4( x, y, object2device[14] / object2device[15], 1 ) ) );
|
||||
}
|
||||
|
||||
inline double plane3_distance_to_point( const Plane3& plane, const Vector3& point ){
|
||||
return vector3_dot( point, plane.normal() ) - plane.dist();
|
||||
}
|
||||
|
||||
inline Vector3 ray_intersect_plane( const Ray& ray, const Plane3& plane ){
|
||||
return ray.origin + vector3_scaled(
|
||||
ray.direction,
|
||||
-plane3_distance_to_point( plane, ray.origin )
|
||||
/ vector3_dot( ray.direction, plane.normal() )
|
||||
);
|
||||
}
|
||||
Vector3 point_on_plane( const Plane3& plane, const Matrix4& object2device, const float x, const float y ){
|
||||
Ray ray;
|
||||
ray_for_device_point( ray, matrix4_full_inverse( object2device ), x, y );
|
||||
return ray_intersect_plane( ray, plane );
|
||||
inline Vector3 point_on_plane( const Plane3& plane, const Matrix4& object2device, const float x, const float y ){
|
||||
return ray_intersect_plane( ray_for_device_point( matrix4_full_inverse( object2device ), x, y ),
|
||||
plane );
|
||||
}
|
||||
|
||||
//! a and b are unit vectors .. returns angle in radians
|
||||
|
|
@ -188,7 +169,7 @@ inline void constrain_to_axis( Vector3& vec, const Vector3& axis ){
|
|||
}
|
||||
|
||||
//! a and b are unit vectors .. a and b must be orthogonal to axis .. returns angle in radians
|
||||
float angle_for_axis( const Vector3& a, const Vector3& b, const Vector3& axis ){
|
||||
inline float angle_for_axis( const Vector3& a, const Vector3& b, const Vector3& axis ){
|
||||
if ( vector3_dot( axis, vector3_cross( a, b ) ) > 0.0 ) {
|
||||
return angle_between( a, b );
|
||||
}
|
||||
|
|
@ -197,7 +178,7 @@ float angle_for_axis( const Vector3& a, const Vector3& b, const Vector3& axis ){
|
|||
}
|
||||
}
|
||||
|
||||
float distance_for_axis( const Vector3& a, const Vector3& b, const Vector3& axis ){
|
||||
inline float distance_for_axis( const Vector3& a, const Vector3& b, const Vector3& axis ){
|
||||
return static_cast<float>( vector3_dot( b, axis ) - vector3_dot( a, axis ) );
|
||||
}
|
||||
|
||||
|
|
@ -244,12 +225,11 @@ RotateFree( Rotatable& rotatable )
|
|||
: m_rotatable( rotatable ){
|
||||
}
|
||||
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
|
||||
point_on_sphere( m_start, device2manip, x, y );
|
||||
m_start = point_on_sphere( device2manip, x, y );
|
||||
vector3_normalise( m_start );
|
||||
}
|
||||
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
|
||||
Vector3 current;
|
||||
point_on_sphere( current, device2manip, x, y );
|
||||
Vector3 current = point_on_sphere( device2manip, x, y );
|
||||
vector3_normalise( current );
|
||||
|
||||
if( snap )
|
||||
|
|
@ -286,7 +266,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
|
|||
vector3_normalise( m_start );
|
||||
}
|
||||
else{
|
||||
point_on_sphere( m_start, device2manip, x, y, m_radius );
|
||||
m_start = point_on_sphere( device2manip, x, y, m_radius );
|
||||
constrain_to_axis( m_start, m_axis );
|
||||
}
|
||||
}
|
||||
|
|
@ -298,7 +278,7 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const
|
|||
vector3_normalise( current );
|
||||
}
|
||||
else{
|
||||
point_on_sphere( current, device2manip, x, y, m_radius );
|
||||
current = point_on_sphere( device2manip, x, y, m_radius );
|
||||
constrain_to_axis( current, m_axis );
|
||||
}
|
||||
|
||||
|
|
@ -365,12 +345,11 @@ TranslateAxis( Translatable& translatable )
|
|||
: m_translatable( translatable ){
|
||||
}
|
||||
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
|
||||
point_on_axis( m_start, m_axis, device2manip, x, y );
|
||||
m_start = point_on_axis( m_axis, device2manip, x, y );
|
||||
m_bounds = bounds;
|
||||
}
|
||||
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
|
||||
Vector3 current;
|
||||
point_on_axis( current, m_axis, device2manip, x, y );
|
||||
Vector3 current = point_on_axis( m_axis, device2manip, x, y );
|
||||
current = vector3_scaled( m_axis, distance_for_axis( m_start, current, m_axis ) );
|
||||
|
||||
translation_local2object( current, current, manip2object );
|
||||
|
|
@ -435,12 +414,11 @@ TranslateFree( Translatable& translatable )
|
|||
: m_translatable( translatable ){
|
||||
}
|
||||
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
|
||||
point_on_plane( m_start, device2manip, x, y );
|
||||
m_start = point_on_plane( device2manip, x, y );
|
||||
m_bounds = bounds;
|
||||
}
|
||||
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
|
||||
Vector3 current;
|
||||
point_on_plane( current, device2manip, x, y );
|
||||
Vector3 current = point_on_plane( device2manip, x, y );
|
||||
current = vector3_subtracted( current, m_start );
|
||||
|
||||
if( snap )
|
||||
|
|
@ -537,7 +515,7 @@ ScaleAxis( Scalable& scalable )
|
|||
: m_scalable( scalable ){
|
||||
}
|
||||
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
|
||||
point_on_axis( m_start, m_axis, device2manip, x, y );
|
||||
m_start = point_on_axis( m_axis, device2manip, x, y );
|
||||
|
||||
m_choosen_extent = Vector3(
|
||||
std::max( bounds.origin[0] + bounds.extents[0] - transform_origin[0], - bounds.origin[0] + bounds.extents[0] + transform_origin[0] ),
|
||||
|
|
@ -548,8 +526,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
|
|||
}
|
||||
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
|
||||
//globalOutputStream() << "manip2object: " << manip2object << " device2manip: " << device2manip << " x: " << x << " y:" << y <<"\n";
|
||||
Vector3 current;
|
||||
point_on_axis( current, m_axis, device2manip, x, y );
|
||||
Vector3 current = point_on_axis( m_axis, device2manip, x, y );
|
||||
Vector3 delta = vector3_subtracted( current, m_start );
|
||||
|
||||
translation_local2object( delta, delta, manip2object );
|
||||
|
|
@ -611,7 +588,7 @@ ScaleFree( Scalable& scalable )
|
|||
: m_scalable( scalable ){
|
||||
}
|
||||
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
|
||||
point_on_plane( m_start, device2manip, x, y );
|
||||
m_start = point_on_plane( device2manip, x, y );
|
||||
|
||||
m_choosen_extent = Vector3(
|
||||
std::max( bounds.origin[0] + bounds.extents[0] - transform_origin[0], -( bounds.origin[0] - bounds.extents[0] - transform_origin[0] ) ),
|
||||
|
|
@ -621,8 +598,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
|
|||
m_bounds = bounds;
|
||||
}
|
||||
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
|
||||
Vector3 current;
|
||||
point_on_plane( current, device2manip, x, y );
|
||||
Vector3 current = point_on_plane( device2manip, x, y );
|
||||
Vector3 delta = vector3_subtracted( current, m_start );
|
||||
|
||||
translation_local2object( delta, delta, manip2object );
|
||||
|
|
@ -866,64 +842,6 @@ Shader* g_state_clipped;
|
|||
RenderableClippedPrimitive g_render_clipped;
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
// dist_Point_to_Line(): get the distance of a point to a line.
|
||||
// Input: a Point P and a Line L (in any dimension)
|
||||
// Return: the shortest distance from P to L
|
||||
float
|
||||
dist_Point_to_Line( Point P, Line L ){
|
||||
Vector v = L.P1 - L.P0;
|
||||
Vector w = P - L.P0;
|
||||
|
||||
double c1 = dot( w,v );
|
||||
double c2 = dot( v,v );
|
||||
double b = c1 / c2;
|
||||
|
||||
Point Pb = L.P0 + b * v;
|
||||
return d( P, Pb );
|
||||
}
|
||||
#endif
|
||||
|
||||
class Segment3D
|
||||
{
|
||||
typedef Vector3 point_type;
|
||||
public:
|
||||
Segment3D( const point_type& _p0, const point_type& _p1 )
|
||||
: p0( _p0 ), p1( _p1 ){
|
||||
}
|
||||
|
||||
point_type p0, p1;
|
||||
};
|
||||
|
||||
typedef Vector3 Point3D;
|
||||
|
||||
inline double vector3_distance_squared( const Point3D& a, const Point3D& b ){
|
||||
return vector3_length_squared( b - a );
|
||||
}
|
||||
|
||||
// get the distance of a point to a segment.
|
||||
Point3D segment_closest_point_to_point( const Segment3D& segment, const Point3D& point ){
|
||||
Vector3 v = segment.p1 - segment.p0;
|
||||
Vector3 w = point - segment.p0;
|
||||
|
||||
double c1 = vector3_dot( w,v );
|
||||
if ( c1 <= 0 ) {
|
||||
return segment.p0;
|
||||
}
|
||||
|
||||
double c2 = vector3_dot( v,v );
|
||||
if ( c2 <= c1 ) {
|
||||
return segment.p1;
|
||||
}
|
||||
|
||||
return Point3D( segment.p0 + v * ( c1 / c2 ) );
|
||||
}
|
||||
|
||||
double segment_dist_to_point_3d( const Segment3D& segment, const Point3D& point ){
|
||||
return vector3_distance_squared( point, segment_closest_point_to_point( segment, point ) );
|
||||
}
|
||||
|
||||
typedef Vector3 point_t;
|
||||
typedef const Vector3* point_iterator_t;
|
||||
|
||||
|
|
@ -985,8 +903,7 @@ void BestPoint( std::size_t count, Vector4 clipped[9], SelectionIntersection& be
|
|||
}
|
||||
|
||||
if ( count == 2 ) {
|
||||
Segment3D segment( normalised[0], normalised[1] );
|
||||
Point3D point = segment_closest_point_to_point( segment, Vector3( 0, 0, 0 ) );
|
||||
const Vector3 point = line_closest_point( Line( normalised[0], normalised[1] ), Vector3( 0, 0, 0 ) );
|
||||
assign_if_closer( best, SelectionIntersection( point.z(), 0 ) );
|
||||
}
|
||||
else if ( count > 2 && !point_test_polygon_2d( Vector3( 0, 0, 0 ), normalised, normalised + count ) ) {
|
||||
|
|
@ -996,11 +913,10 @@ void BestPoint( std::size_t count, Vector4 clipped[9], SelectionIntersection& be
|
|||
plane = &plaine;
|
||||
}
|
||||
//globalOutputStream() << plane.a << " " << plane.b << " " << plane.c << " " << "\n";
|
||||
point_iterator_t end = normalised + count;
|
||||
const point_iterator_t end = normalised + count;
|
||||
for ( point_iterator_t previous = end - 1, current = normalised; current != end; previous = current, ++current )
|
||||
{
|
||||
Segment3D segment( *previous, *current );
|
||||
Point3D point = segment_closest_point_to_point( segment, Vector3( 0, 0, 0 ) );
|
||||
Vector3 point = line_closest_point( Line( *previous, *current ), Vector3( 0, 0, 0 ) );
|
||||
float depth = point.z();
|
||||
point.z() = 0;
|
||||
float distance = static_cast<float>( vector3_length_squared( point ) );
|
||||
|
|
@ -2722,11 +2638,10 @@ class PlaneSelectable_bestPlaneIndirect : public scene::Graph::Walker
|
|||
SelectionTest& m_test;
|
||||
Plane3& m_plane;
|
||||
Vector3& m_intersection;
|
||||
const Vector3& m_viewer;
|
||||
mutable float m_dist;
|
||||
public:
|
||||
PlaneSelectable_bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, const Vector3& viewer )
|
||||
: m_test( test ), m_plane( plane ), m_intersection( intersection ), m_viewer( viewer ), m_dist( FLT_MAX ){
|
||||
PlaneSelectable_bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection )
|
||||
: m_test( test ), m_plane( plane ), m_intersection( intersection ), m_dist( FLT_MAX ){
|
||||
}
|
||||
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||
if ( path.top().get().visible() ) {
|
||||
|
|
@ -2734,7 +2649,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
|||
if ( selectable != 0 && selectable->isSelected() ) {
|
||||
PlaneSelectable* planeSelectable = Instance_getPlaneSelectable( instance );
|
||||
if ( planeSelectable != 0 ) {
|
||||
planeSelectable->bestPlaneIndirect( m_test, m_plane, m_intersection, m_dist, m_viewer );
|
||||
planeSelectable->bestPlaneIndirect( m_test, m_plane, m_intersection, m_dist );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2763,7 +2678,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
|||
}
|
||||
};
|
||||
|
||||
bool Scene_forEachPlaneSelectable_selectPlanes2( scene::Graph& graph, SelectionTest& test, const Vector3& viewer, TranslateAxis2& translateAxis ){
|
||||
bool Scene_forEachPlaneSelectable_selectPlanes2( scene::Graph& graph, SelectionTest& test, TranslateAxis2& translateAxis ){
|
||||
Plane3 plane( 0, 0, 0, 0 );
|
||||
graph.traverse( PlaneSelectable_bestPlaneDirect( test, plane ) );
|
||||
if( plane3_valid( plane ) ){
|
||||
|
|
@ -2772,7 +2687,7 @@ bool Scene_forEachPlaneSelectable_selectPlanes2( scene::Graph& graph, SelectionT
|
|||
}
|
||||
else{
|
||||
Vector3 intersection;
|
||||
graph.traverse( PlaneSelectable_bestPlaneIndirect( test, plane, intersection, viewer ) );
|
||||
graph.traverse( PlaneSelectable_bestPlaneIndirect( test, plane, intersection ) );
|
||||
if( plane3_valid( plane ) ){
|
||||
test.BeginMesh( g_matrix4_identity );
|
||||
/* may introduce some screen space offset in manipulatable to handle far-from-edge clicks perfectly; thought clicking not so far isn't too nasty, right? */
|
||||
|
|
@ -3895,7 +3810,7 @@ Vector3 testSelected_scene_snapped_point( const SelectionVolume& test, ClipperSe
|
|||
}
|
||||
}
|
||||
{ /* try edges */
|
||||
Vector3 edgePoint = segment_closest_point_to_point( Segment3D( ( *prev ).vertex, ( *curr ).vertex ), point );
|
||||
Vector3 edgePoint = line_closest_point( Line( ( *prev ).vertex, ( *curr ).vertex ), point );
|
||||
if( edgePoint != ( *prev ).vertex && edgePoint != ( *curr ).vertex ){
|
||||
const Vector3 edgedir = vector3_normalised( ( *curr ).vertex - ( *prev ).vertex );
|
||||
const std::size_t maxi = vector3_max_abs_component_index( edgedir );
|
||||
|
|
@ -4026,7 +3941,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
if( GlobalSelectionSystem().countSelected() != 0 ){
|
||||
if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){
|
||||
if( g_bAltResize_AltSelect && view.fill() ){
|
||||
m_selected2 = Scene_forEachPlaneSelectable_selectPlanes2( GlobalSceneGraph(), test, Manipulatable::m_view->getViewer(), m_axisResize );
|
||||
m_selected2 = Scene_forEachPlaneSelectable_selectPlanes2( GlobalSceneGraph(), test, m_axisResize );
|
||||
}
|
||||
else{
|
||||
BooleanSelector booleanSelector;
|
||||
|
|
@ -4492,11 +4407,10 @@ TransformOriginTranslate( TransformOriginTranslatable& transformOriginTranslatab
|
|||
: m_transformOriginTranslatable( transformOriginTranslatable ){
|
||||
}
|
||||
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
|
||||
point_on_plane( m_start, device2manip, x, y );
|
||||
m_start = point_on_plane( device2manip, x, y );
|
||||
}
|
||||
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
|
||||
Vector3 current;
|
||||
point_on_plane( current, device2manip, x, y );
|
||||
Vector3 current = point_on_plane( device2manip, x, y );
|
||||
current = vector3_subtracted( current, m_start );
|
||||
|
||||
if( snap ){
|
||||
|
|
|
|||
|
|
@ -1557,7 +1557,7 @@ void Face_setTexture( Face& face, const char* shader, const FaceTexture& clipboa
|
|||
face.ProjectTexture( clipboard.m_projection, clipboard.m_plane.normal() );
|
||||
}
|
||||
else if( mode == ePasteSeamless ){
|
||||
DoubleLine line = plane3_intersect_plane3( clipboard.m_plane, face.getPlane().plane3() );
|
||||
DoubleRay line = plane3_intersect_plane3( clipboard.m_plane, face.getPlane().plane3() );
|
||||
if( vector3_length_squared( line.direction ) == 0 ){
|
||||
face.ProjectTexture( clipboard.m_projection, clipboard.m_plane.normal() );
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -26,66 +26,6 @@
|
|||
#include "math/line.h"
|
||||
|
||||
|
||||
inline double plane3_distance_to_point( const Plane3& plane, const DoubleVector3& point ){
|
||||
return vector3_dot( point, plane.normal() ) - plane.dist();
|
||||
}
|
||||
|
||||
inline double plane3_distance_to_point( const Plane3& plane, const Vector3& point ){
|
||||
return vector3_dot( point, plane.normal() ) - plane.dist();
|
||||
}
|
||||
|
||||
/// \brief Returns the point at which \p line intersects \p plane, or an undefined value if there is no intersection.
|
||||
inline DoubleVector3 line_intersect_plane( const DoubleLine& line, const Plane3& plane ){
|
||||
return line.origin + vector3_scaled(
|
||||
line.direction,
|
||||
-plane3_distance_to_point( plane, line.origin )
|
||||
/ vector3_dot( line.direction, plane.normal() )
|
||||
);
|
||||
}
|
||||
|
||||
inline bool float_is_largest_absolute( double axis, double other ){
|
||||
return fabs( axis ) > fabs( other );
|
||||
}
|
||||
|
||||
/// \brief Returns the index of the component of \p v that has the largest absolute value.
|
||||
inline int vector3_largest_absolute_component_index( const DoubleVector3& v ){
|
||||
return ( float_is_largest_absolute( v[1], v[0] ) )
|
||||
? ( float_is_largest_absolute( v[1], v[2] ) )
|
||||
? 1
|
||||
: 2
|
||||
: ( float_is_largest_absolute( v[0], v[2] ) )
|
||||
? 0
|
||||
: 2;
|
||||
}
|
||||
|
||||
/// \brief Returns the infinite line that is the intersection of \p plane and \p other.
|
||||
DoubleLine plane3_intersect_plane3( const Plane3& plane, const Plane3& other ){
|
||||
DoubleLine line;
|
||||
line.direction = vector3_cross( plane.normal(), other.normal() );
|
||||
switch ( vector3_largest_absolute_component_index( line.direction ) )
|
||||
{
|
||||
case 0:
|
||||
line.origin.x() = 0;
|
||||
line.origin.y() = ( -other.dist() * plane.normal().z() - -plane.dist() * other.normal().z() ) / line.direction.x();
|
||||
line.origin.z() = ( -plane.dist() * other.normal().y() - -other.dist() * plane.normal().y() ) / line.direction.x();
|
||||
break;
|
||||
case 1:
|
||||
line.origin.x() = ( -plane.dist() * other.normal().z() - -other.dist() * plane.normal().z() ) / line.direction.y();
|
||||
line.origin.y() = 0;
|
||||
line.origin.z() = ( -other.dist() * plane.normal().x() - -plane.dist() * other.normal().x() ) / line.direction.y();
|
||||
break;
|
||||
case 2:
|
||||
line.origin.x() = ( -other.dist() * plane.normal().y() - -plane.dist() * other.normal().y() ) / line.direction.z();
|
||||
line.origin.y() = ( -plane.dist() * other.normal().x() - -other.dist() * plane.normal().x() ) / line.direction.z();
|
||||
line.origin.z() = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include "math/aabb.h"
|
||||
void windingTestInfinity(){
|
||||
|
|
@ -158,7 +98,7 @@ void windingTestInfinity(){
|
|||
for( ; i < winding.size(); ++i ){
|
||||
for( std::size_t j = 0; j < 6; ++j ){
|
||||
if( vector3_dot( winding[i].edge.direction, worldplanes[j].normal() ) != 0 ){
|
||||
const DoubleVector3 v = line_intersect_plane( winding[i].edge, worldplanes[j] );
|
||||
const DoubleVector3 v = ray_intersect_plane( winding[i].edge, worldplanes[j] );
|
||||
if( aabb_intersects_point( world, v ) ){
|
||||
// globalWarningStream() << " INFINITE POINT INSIDE WORLD\n";
|
||||
++windingTestInfinity_FAIL;
|
||||
|
|
@ -226,7 +166,7 @@ void Winding_createInfinite( FixedWinding& winding, const Plane3& plane, double
|
|||
|
||||
// project a really big axis aligned box onto the plane
|
||||
|
||||
DoubleLine r1, r2, r3, r4;
|
||||
DoubleRay r1, r2, r3, r4;
|
||||
r1.origin = vector3_added( vector3_subtracted( org, vright ), vup );
|
||||
r1.direction = vector3_normalised( vright );
|
||||
winding.push_back( FixedWindingVertex( r1.origin, r1, c_brush_maxFaces ) );
|
||||
|
|
@ -258,7 +198,7 @@ void Winding_createInfinite( FixedWinding& winding, const Plane3& plane, double
|
|||
|
||||
// project a really big axis aligned box onto the plane
|
||||
|
||||
DoubleLine ray;
|
||||
DoubleRay ray;
|
||||
ray.origin = org - vright + vup;
|
||||
ray.direction = vector3_normalised( vright0 );
|
||||
winding.push_back( FixedWindingVertex( ray.origin, ray, c_brush_maxFaces ) );
|
||||
|
|
@ -368,7 +308,7 @@ void Winding_Clip( const FixedWinding& winding, const Plane3& plane, const Plane
|
|||
else
|
||||
{
|
||||
// append intersection point of line and plane to output winding
|
||||
DoubleVector3 mid( line_intersect_plane( vertex.edge, clipPlane ) );
|
||||
DoubleVector3 mid( ray_intersect_plane( vertex.edge, clipPlane ) );
|
||||
|
||||
if ( classification == ePlaneFront ) {
|
||||
// this edge lies on the clip plane
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "math/vector.h"
|
||||
#include "math/line.h"
|
||||
#include "container/array.h"
|
||||
|
||||
enum ProjectionAxis
|
||||
|
|
@ -148,21 +149,14 @@ struct Winding
|
|||
}
|
||||
};
|
||||
|
||||
class DoubleLine
|
||||
{
|
||||
public:
|
||||
DoubleVector3 origin;
|
||||
DoubleVector3 direction;
|
||||
};
|
||||
|
||||
class FixedWindingVertex
|
||||
{
|
||||
public:
|
||||
DoubleVector3 vertex;
|
||||
DoubleLine edge;
|
||||
DoubleRay edge;
|
||||
std::size_t adjacent;
|
||||
|
||||
FixedWindingVertex( const DoubleVector3& vertex_, const DoubleLine& edge_, std::size_t adjacent_ )
|
||||
FixedWindingVertex( const DoubleVector3& vertex_, const DoubleRay& edge_, std::size_t adjacent_ )
|
||||
: vertex( vertex_ ), edge( edge_ ), adjacent( adjacent_ ){
|
||||
}
|
||||
};
|
||||
|
|
@ -234,8 +228,6 @@ inline std::size_t Winding_next( const Winding& winding, std::size_t i ){
|
|||
}
|
||||
|
||||
|
||||
class Plane3;
|
||||
|
||||
void Winding_createInfinite( FixedWinding& w, const Plane3& plane, double infinity );
|
||||
|
||||
const double ON_EPSILON = 1.0 / ( 1 << 8 );
|
||||
|
|
@ -285,6 +277,4 @@ inline void Winding_printConnectivity( Winding& winding ){
|
|||
}
|
||||
}
|
||||
|
||||
DoubleLine plane3_intersect_plane3( const Plane3& plane, const Plane3& other );
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user