binds... * alt + m1 in camera: new resizing mode for brushes, curves and doom3 lights with direct and indirect selection methods
This commit is contained in:
parent
f99cf57f27
commit
9c91f4fa78
|
|
@ -290,6 +290,7 @@ public:
|
||||||
virtual bool contains( const Plane3& plane ) const = 0;
|
virtual bool contains( const Plane3& plane ) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \todo Support localToWorld.
|
||||||
class PlaneSelectable
|
class PlaneSelectable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -297,6 +298,10 @@ STRING_CONSTANT( Name, "PlaneSelectable" );
|
||||||
|
|
||||||
virtual void selectPlanes( Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback ) = 0;
|
virtual void selectPlanes( Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback ) = 0;
|
||||||
virtual void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPlanes ) = 0;
|
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 selectByPlane( const Plane3& plane ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,143 @@ void selectReversedPlanes( const AABB& aabb, Selector& selector, const SelectedP
|
||||||
if ( selectedPlanes.contains( plane3_flipped( planes[i] ) ) )
|
if ( selectedPlanes.contains( plane3_flipped( planes[i] ) ) )
|
||||||
Selector_add( selector, m_selectables[i] );
|
Selector_add( selector, m_selectables[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bestPlaneDirect( const AABB& aabb, SelectionTest& test, Plane3& plane, SelectionIntersection& intersection, const Matrix4& rotation = g_matrix4_identity ){
|
||||||
|
AABB aabb_ = aabb;
|
||||||
|
for( std::size_t i = 0; i < 3; ++i ) /* make sides of flat patches more selectable */
|
||||||
|
if( aabb_.extents[i] < 1 )
|
||||||
|
aabb_.extents[i] = 4;
|
||||||
|
|
||||||
|
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 ){
|
||||||
|
const std::size_t index = i * 4;
|
||||||
|
SelectionIntersection intersection_new;
|
||||||
|
test.TestQuads( VertexPointer( reinterpret_cast<VertexPointer::pointer>( corners ), sizeof( Vector3 ) ), IndexPointer( &indices[index], 4 ), intersection_new );
|
||||||
|
if( SelectionIntersection_closer( intersection_new, intersection ) ){
|
||||||
|
intersection = intersection_new;
|
||||||
|
plane = planes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 ){
|
||||||
|
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
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
|
||||||
|
0 ----- 1
|
||||||
|
/| /|
|
||||||
|
/ | / |
|
||||||
|
/ | / |
|
||||||
|
3 ----- 2 |
|
||||||
|
| 4|_|___|5
|
||||||
|
| / | /
|
||||||
|
| / | /
|
||||||
|
|/ | /
|
||||||
|
7|_____|/6
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
const std::size_t edges[24] = {
|
||||||
|
0, 1,
|
||||||
|
1, 2,
|
||||||
|
2, 3,
|
||||||
|
3, 0,
|
||||||
|
4, 5,
|
||||||
|
5, 6,
|
||||||
|
6, 7,
|
||||||
|
7, 4,
|
||||||
|
0, 4,
|
||||||
|
1, 5,
|
||||||
|
2, 6,
|
||||||
|
3, 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::size_t adjacent_planes[24] = {
|
||||||
|
4, 2,
|
||||||
|
4, 0,
|
||||||
|
4, 3,
|
||||||
|
4, 1,
|
||||||
|
5, 2,
|
||||||
|
5, 0,
|
||||||
|
5, 3,
|
||||||
|
5, 1,
|
||||||
|
1, 2,
|
||||||
|
2, 0,
|
||||||
|
0, 3,
|
||||||
|
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
|
||||||
|
plane = plane2;
|
||||||
|
intersection = intersection_new;
|
||||||
|
dist = dist_new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_bounds = aabb;
|
||||||
|
}
|
||||||
|
void selectByPlane( const AABB& aabb, const Plane3& plane, const Matrix4& rotation = g_matrix4_identity ){
|
||||||
|
Plane3 planes[6];
|
||||||
|
aabb_planes_oriented( aabb, rotation, planes );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AABB evaluateResize( const Vector3& translation ) const {
|
AABB evaluateResize( const Vector3& translation ) const {
|
||||||
Vector3 min = m_bounds.origin - m_bounds.extents;
|
Vector3 min = m_bounds.origin - m_bounds.extents;
|
||||||
Vector3 max = m_bounds.origin + m_bounds.extents;
|
Vector3 max = m_bounds.origin + m_bounds.extents;
|
||||||
|
|
|
||||||
|
|
@ -1867,6 +1867,25 @@ void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPla
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bestPlaneDirect( SelectionTest& test, Plane3& plane, SelectionIntersection& intersection ){
|
||||||
|
if ( g_lightType == LIGHTTYPE_DOOM3 ) {
|
||||||
|
test.BeginMesh( localToWorld() );
|
||||||
|
m_dragPlanes.bestPlaneDirect( m_contained.aabb(), test, plane, intersection, rotation() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, const Vector3& viewer ){
|
||||||
|
if ( g_lightType == LIGHTTYPE_DOOM3 ) {
|
||||||
|
test.BeginMesh( localToWorld() );
|
||||||
|
m_dragPlanes.bestPlaneIndirect( m_contained.aabb(), test, plane, intersection, dist, viewer, rotation() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void selectByPlane( const Plane3& plane ){
|
||||||
|
if ( g_lightType == LIGHTTYPE_DOOM3 ) {
|
||||||
|
m_dragPlanes.selectByPlane( m_contained.aabb(), plane, rotation() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isSelectedComponents() const {
|
bool isSelectedComponents() const {
|
||||||
if ( g_lightType == LIGHTTYPE_DOOM3 ) {
|
if ( g_lightType == LIGHTTYPE_DOOM3 ) {
|
||||||
return m_dragPlanes.isSelected();
|
return m_dragPlanes.isSelected();
|
||||||
|
|
|
||||||
|
|
@ -1509,6 +1509,16 @@ Face& getFace() const {
|
||||||
void testSelect( SelectionTest& test, SelectionIntersection& best ){
|
void testSelect( SelectionTest& test, SelectionIntersection& best ){
|
||||||
test.TestPoint( getEdge(), 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
|
class SelectableVertex
|
||||||
|
|
@ -3042,6 +3052,28 @@ void testSelect( Selector& selector, SelectionTest& test ){
|
||||||
Selector_add( selector, *this, best );
|
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;
|
||||||
|
intersection = intersection_new;
|
||||||
|
dist = dist_new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VertexInstance : public Selectable
|
class VertexInstance : public Selectable
|
||||||
|
|
@ -3588,6 +3620,31 @@ void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPla
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bestPlaneDirect( SelectionTest& test, Plane3& plane, SelectionIntersection& intersection ){
|
||||||
|
test.BeginMesh( localToWorld() );
|
||||||
|
for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
|
||||||
|
{
|
||||||
|
SelectionIntersection intersection_new;
|
||||||
|
( *i ).testSelect( test, intersection_new );
|
||||||
|
if( SelectionIntersection_closer( intersection_new, intersection ) ){
|
||||||
|
intersection = intersection_new;
|
||||||
|
plane = ( *i ).getFace().plane3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void bestPlaneIndirect( SelectionTest& test, Plane3& plane, Vector3& intersection, float& dist, const Vector3& viewer ){
|
||||||
|
test.BeginMesh( localToWorld() );
|
||||||
|
for ( EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i )
|
||||||
|
{
|
||||||
|
( *i ).bestPlaneIndirect( test, plane, intersection, dist, viewer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void selectByPlane( const Plane3& plane ){
|
||||||
|
for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
|
||||||
|
if( plane3_equal( plane, ( *i ).getFace().plane3() ) || plane3_equal( plane, plane3_flipped( ( *i ).getFace().plane3() ) ) )
|
||||||
|
( *i ).setSelected( SelectionSystem::eFace, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void selectVerticesOnPlanes( SelectionTest& test ){
|
void selectVerticesOnPlanes( SelectionTest& test ){
|
||||||
FaceInstances_ptrs bestInstances;
|
FaceInstances_ptrs bestInstances;
|
||||||
|
|
|
||||||
|
|
@ -1617,6 +1617,18 @@ void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPla
|
||||||
m_dragPlanes.selectReversedPlanes( m_patch.localAABB(), selector, selectedPlanes );
|
m_dragPlanes.selectReversedPlanes( m_patch.localAABB(), selector, selectedPlanes );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bestPlaneDirect( SelectionTest& test, Plane3& plane, SelectionIntersection& intersection ){
|
||||||
|
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 ){
|
||||||
|
test.BeginMesh( localToWorld() );
|
||||||
|
m_dragPlanes.bestPlaneIndirect( m_patch.localAABB(), test, plane, intersection, dist, viewer );
|
||||||
|
}
|
||||||
|
void selectByPlane( const Plane3& plane ){
|
||||||
|
m_dragPlanes.selectByPlane( m_patch.localAABB(), plane );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void snapComponents( float snap ){
|
void snapComponents( float snap ){
|
||||||
if ( selectedVertices() ) {
|
if ( selectedVertices() ) {
|
||||||
|
|
|
||||||
|
|
@ -438,6 +438,49 @@ void SetAxis( const Vector3& axis ){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TranslateAxis2 : public Manipulatable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Vector3 m_0;
|
||||||
|
std::size_t m_axisZ;
|
||||||
|
Plane3 m_planeZ;
|
||||||
|
Vector3 m_startZ;
|
||||||
|
Translatable& m_translatable;
|
||||||
|
AABB m_bounds;
|
||||||
|
public:
|
||||||
|
TranslateAxis2( Translatable& translatable )
|
||||||
|
: m_translatable( translatable ){
|
||||||
|
}
|
||||||
|
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
|
||||||
|
if( m_0 == g_vector3_identity ) /* special value to indicate missing good point to start with */
|
||||||
|
m_0 = transform_origin;
|
||||||
|
#if 0
|
||||||
|
Vector3 xydir( m_view->getViewDir() );
|
||||||
|
#else
|
||||||
|
Vector3 xydir( m_view->getViewer() - m_0 );
|
||||||
|
#endif
|
||||||
|
xydir[m_axisZ] = 0;
|
||||||
|
vector3_normalise( xydir );
|
||||||
|
m_planeZ = Plane3( xydir, vector3_dot( xydir, m_0 ) );
|
||||||
|
m_startZ = point_on_plane( m_planeZ, m_view->GetViewMatrix(), 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( m_planeZ, m_view->GetViewMatrix(), x, y ) - m_startZ ) * g_vector3_axes[m_axisZ];
|
||||||
|
|
||||||
|
if( snapbbox )
|
||||||
|
aabb_snap_translation( current, m_bounds );
|
||||||
|
else
|
||||||
|
vector3_snap( current, GetSnapGridSize() );
|
||||||
|
|
||||||
|
m_translatable.translate( current );
|
||||||
|
}
|
||||||
|
void set0( const Vector3& start, std::size_t axis ){
|
||||||
|
m_0 = start;
|
||||||
|
m_axisZ = axis;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class TranslateFree : public Manipulatable
|
class TranslateFree : public Manipulatable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
@ -2701,6 +2744,99 @@ bool Scene_forEachPlaneSelectable_selectPlanes( scene::Graph& graph, Selector& s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class PlaneSelectable_bestPlaneDirect : public scene::Graph::Walker
|
||||||
|
{
|
||||||
|
SelectionTest& m_test;
|
||||||
|
Plane3& m_plane;
|
||||||
|
mutable SelectionIntersection m_intersection;
|
||||||
|
public:
|
||||||
|
PlaneSelectable_bestPlaneDirect( SelectionTest& test, Plane3& plane )
|
||||||
|
: m_test( test ), m_plane( plane ), m_intersection(){
|
||||||
|
}
|
||||||
|
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||||
|
if ( path.top().get().visible() ) {
|
||||||
|
Selectable* selectable = Instance_getSelectable( instance );
|
||||||
|
if ( selectable != 0 && selectable->isSelected() ) {
|
||||||
|
PlaneSelectable* planeSelectable = Instance_getPlaneSelectable( instance );
|
||||||
|
if ( planeSelectable != 0 ) {
|
||||||
|
planeSelectable->bestPlaneDirect( m_test, m_plane, m_intersection );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
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 ){
|
||||||
|
}
|
||||||
|
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||||
|
if ( path.top().get().visible() ) {
|
||||||
|
Selectable* selectable = Instance_getSelectable( instance );
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PlaneSelectable_selectByPlane : public scene::Graph::Walker
|
||||||
|
{
|
||||||
|
const Plane3 m_plane;
|
||||||
|
public:
|
||||||
|
PlaneSelectable_selectByPlane( const Plane3& plane )
|
||||||
|
: m_plane( plane ){
|
||||||
|
}
|
||||||
|
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||||
|
if ( path.top().get().visible() ) {
|
||||||
|
Selectable* selectable = Instance_getSelectable( instance );
|
||||||
|
if ( selectable != 0 && selectable->isSelected() ) {
|
||||||
|
PlaneSelectable* planeSelectable = Instance_getPlaneSelectable( instance );
|
||||||
|
if ( planeSelectable != 0 ) {
|
||||||
|
planeSelectable->selectByPlane( m_plane );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool Scene_forEachPlaneSelectable_selectPlanes2( scene::Graph& graph, SelectionTest& test, const Vector3& viewer, TranslateAxis2& translateAxis ){
|
||||||
|
Plane3 plane( 0, 0, 0, 0 );
|
||||||
|
graph.traverse( PlaneSelectable_bestPlaneDirect( test, plane ) );
|
||||||
|
if( plane3_valid( plane ) ){
|
||||||
|
test.BeginMesh( g_matrix4_identity );
|
||||||
|
translateAxis.set0( point_on_plane( plane, test.getVolume().GetViewMatrix(), 0, 0 ), vector3_max_abs_component_index( plane.normal() ) );
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Vector3 intersection;
|
||||||
|
graph.traverse( PlaneSelectable_bestPlaneIndirect( test, plane, intersection, viewer ) );
|
||||||
|
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? */
|
||||||
|
translateAxis.set0( vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( intersection, 1 ) ) ), vector3_max_abs_component_index( plane.normal() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( plane3_valid( plane ) ){
|
||||||
|
graph.traverse( PlaneSelectable_selectByPlane( plane ) );
|
||||||
|
}
|
||||||
|
return plane3_valid( plane );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "brush.h"
|
#include "brush.h"
|
||||||
|
|
||||||
class TestedBrushFacesSelectVeritces : public scene::Graph::Walker
|
class TestedBrushFacesSelectVeritces : public scene::Graph::Walker
|
||||||
|
|
@ -3617,6 +3753,7 @@ bool g_bTmpComponentMode = false;
|
||||||
class DragManipulator : public Manipulator
|
class DragManipulator : public Manipulator
|
||||||
{
|
{
|
||||||
TranslateFree m_freeResize;
|
TranslateFree m_freeResize;
|
||||||
|
TranslateAxis2 m_axisResize;
|
||||||
TranslateFree m_freeDrag;
|
TranslateFree m_freeDrag;
|
||||||
TranslateFreeXY_Z m_freeDragXY_Z;
|
TranslateFreeXY_Z m_freeDragXY_Z;
|
||||||
ResizeTranslatable m_resize;
|
ResizeTranslatable m_resize;
|
||||||
|
|
@ -3624,11 +3761,12 @@ DragTranslatable m_drag;
|
||||||
DragNewBrush m_dragNewBrush;
|
DragNewBrush m_dragNewBrush;
|
||||||
bool m_dragSelected; //drag selected primitives or components
|
bool m_dragSelected; //drag selected primitives or components
|
||||||
bool m_selected; //components selected temporally for drag
|
bool m_selected; //components selected temporally for drag
|
||||||
|
bool m_selected2; //planeselectables in cam with alt
|
||||||
bool m_newBrush;
|
bool m_newBrush;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DragManipulator() : m_freeResize( m_resize ), m_freeDrag( m_drag ), m_freeDragXY_Z( m_drag ), m_selected( false ), m_newBrush( false ){
|
DragManipulator() : m_freeResize( m_resize ), m_axisResize( m_resize ), m_freeDrag( m_drag ), m_freeDragXY_Z( m_drag ), m_dragSelected( false ), m_selected( false ), m_selected2( false ), m_newBrush( false ){
|
||||||
}
|
}
|
||||||
|
|
||||||
Manipulatable* GetManipulatable(){
|
Manipulatable* GetManipulatable(){
|
||||||
|
|
@ -3636,6 +3774,8 @@ Manipulatable* GetManipulatable(){
|
||||||
return &m_dragNewBrush;
|
return &m_dragNewBrush;
|
||||||
else if( m_selected )
|
else if( m_selected )
|
||||||
return &m_freeResize;
|
return &m_freeResize;
|
||||||
|
else if( m_selected2 )
|
||||||
|
return &m_axisResize;
|
||||||
else if( Manipulatable::m_view->fill() )
|
else if( Manipulatable::m_view->fill() )
|
||||||
return &m_freeDragXY_Z;
|
return &m_freeDragXY_Z;
|
||||||
else
|
else
|
||||||
|
|
@ -3648,32 +3788,37 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
||||||
|
|
||||||
if( GlobalSelectionSystem().countSelected() != 0 ){
|
if( GlobalSelectionSystem().countSelected() != 0 ){
|
||||||
if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){
|
if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){
|
||||||
BooleanSelector booleanSelector;
|
if( g_bAltResize_AltSelect && view.fill() ){
|
||||||
Scene_TestSelect_Primitive( booleanSelector, test, view );
|
m_selected2 = Scene_forEachPlaneSelectable_selectPlanes2( GlobalSceneGraph(), test, Manipulatable::m_view->getViewer(), m_axisResize );
|
||||||
|
|
||||||
if ( booleanSelector.isSelected() ) { /* hit a primitive */
|
|
||||||
if( g_bAltResize_AltSelect ){
|
|
||||||
DeepBestSelector deepSelector;
|
|
||||||
Scene_TestSelect_Component_Selected( deepSelector, test, view, SelectionSystem::eVertex ); /* try to quickly select hit vertices */
|
|
||||||
for ( std::list<Selectable*>::iterator i = deepSelector.best().begin(); i != deepSelector.best().end(); ++i )
|
|
||||||
selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) );
|
|
||||||
if( deepSelector.best().empty() ) /* otherwise drag clicked face's vertices */
|
|
||||||
Scene_forEachTestedBrushFace_selectVertices( GlobalSceneGraph(), test );
|
|
||||||
m_selected = true;
|
|
||||||
}
|
|
||||||
else{ /* drag a primitive */
|
|
||||||
m_dragSelected = true;
|
|
||||||
test.BeginMesh( g_matrix4_identity, true );
|
|
||||||
m_freeDragXY_Z.set0( vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, booleanSelector.bestIntersection().depth(), 1 ) ) ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{ /* haven't hit a primitive */
|
else{
|
||||||
if( g_bAltResize_AltSelect ){
|
BooleanSelector booleanSelector;
|
||||||
Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test ); /* select vertices on planeSelectables */
|
Scene_TestSelect_Primitive( booleanSelector, test, view );
|
||||||
m_selected = true;
|
|
||||||
|
if ( booleanSelector.isSelected() ) { /* hit a primitive */
|
||||||
|
if( g_bAltResize_AltSelect ){
|
||||||
|
DeepBestSelector deepSelector;
|
||||||
|
Scene_TestSelect_Component_Selected( deepSelector, test, view, SelectionSystem::eVertex ); /* try to quickly select hit vertices */
|
||||||
|
for ( std::list<Selectable*>::iterator i = deepSelector.best().begin(); i != deepSelector.best().end(); ++i )
|
||||||
|
selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) );
|
||||||
|
if( deepSelector.best().empty() ) /* otherwise drag clicked face's vertices */
|
||||||
|
Scene_forEachTestedBrushFace_selectVertices( GlobalSceneGraph(), test );
|
||||||
|
m_selected = true;
|
||||||
|
}
|
||||||
|
else{ /* drag a primitive */
|
||||||
|
m_dragSelected = true;
|
||||||
|
test.BeginMesh( g_matrix4_identity, true );
|
||||||
|
m_freeDragXY_Z.set0( vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, booleanSelector.bestIntersection().depth(), 1 ) ) ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{ /* haven't hit a primitive */
|
||||||
m_selected = Scene_forEachPlaneSelectable_selectPlanes( GlobalSceneGraph(), selector, test ); /* select faces on planeSelectables */
|
if( g_bAltResize_AltSelect ){
|
||||||
|
Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test ); /* select vertices on planeSelectables */
|
||||||
|
m_selected = true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
m_selected = Scene_forEachPlaneSelectable_selectPlanes( GlobalSceneGraph(), selector, test ); /* select faces on planeSelectables */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3698,7 +3843,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
||||||
|
|
||||||
for ( SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i )
|
for ( SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i )
|
||||||
( *i ).second->setSelected( true );
|
( *i ).second->setSelected( true );
|
||||||
g_bTmpComponentMode = m_selected;
|
g_bTmpComponentMode = m_selected | m_selected2;
|
||||||
}
|
}
|
||||||
else if( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){
|
else if( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){
|
||||||
m_newBrush = true;
|
m_newBrush = true;
|
||||||
|
|
@ -3722,10 +3867,11 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
||||||
void setSelected( bool select ){
|
void setSelected( bool select ){
|
||||||
m_dragSelected = select;
|
m_dragSelected = select;
|
||||||
m_selected = select;
|
m_selected = select;
|
||||||
|
m_selected2 = select;
|
||||||
m_newBrush = select;
|
m_newBrush = select;
|
||||||
}
|
}
|
||||||
bool isSelected() const {
|
bool isSelected() const {
|
||||||
return m_dragSelected || m_selected || m_newBrush;
|
return m_dragSelected || m_selected || m_selected2 || m_newBrush;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -5226,9 +5372,13 @@ bool RadiantSelectionSystem::endMove(){
|
||||||
|
|
||||||
freezeTransforms();
|
freezeTransforms();
|
||||||
|
|
||||||
if ( Mode() == ePrimitive && ManipulatorMode() == eDrag ) {
|
// if ( Mode() == ePrimitive && ManipulatorMode() == eDrag ) {
|
||||||
|
// g_bTmpComponentMode = false;
|
||||||
|
// Scene_SelectAll_Component( false, g_bAltResize_AltSelect? SelectionSystem::eVertex : SelectionSystem::eFace );
|
||||||
|
// }
|
||||||
|
if( g_bTmpComponentMode ){
|
||||||
g_bTmpComponentMode = false;
|
g_bTmpComponentMode = false;
|
||||||
Scene_SelectAll_Component( false, g_bAltResize_AltSelect? SelectionSystem::eVertex : SelectionSystem::eFace );
|
setSelectedAllComponents( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pivot_moving = false;
|
m_pivot_moving = false;
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ void construct(){
|
||||||
|
|
||||||
m_frustum = frustum_from_viewproj( m_viewproj );
|
m_frustum = frustum_from_viewproj( m_viewproj );
|
||||||
m_viewer = viewer_from_viewproj( m_viewproj );
|
m_viewer = viewer_from_viewproj( m_viewproj );
|
||||||
m_viewdir = vector3_normalised( fill()? Vector3( -m_modelview[2], -m_modelview[6], -m_modelview[10] ) : Vector3( m_modelview[2], m_modelview[6], m_modelview[10] ) );
|
m_viewdir = vector3_normalised( fill()? Vector3( -m_modelview[2], -m_modelview[6], -m_modelview[10] ) : Vector3( m_modelview[2], m_modelview[6], m_modelview[10] ) );
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
View( bool fill = false ) :
|
View( bool fill = false ) :
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user