void CurveCreateTool::PickPosition(int x, int y, Vector3 &position) { FrustumLinePickVisitor pick (m_Scene->GetViewport()->GetCamera(), x, y); // pick in the world m_PickWorld.Raise( PickArgs( &pick ) ); bool set = false; if (s_SurfaceSnap || s_ObjectSnap) { V_PickHitSmartPtr sorted; PickHit::Sort(m_Scene->GetViewport()->GetCamera(), pick.GetHits(), sorted, PickSortTypes::Intersection); V_PickHitSmartPtr::const_iterator itr = sorted.begin(); V_PickHitSmartPtr::const_iterator end = sorted.end(); for ( ; itr != end; ++itr ) { // don't snap if we are surface snapping with no normal if ( s_SurfaceSnap && !(*itr)->HasNormal() ) { continue; } if ( (*itr)->GetHitObject() != m_Instance ) { SceneGraph::HierarchyNode* node = Reflect::SafeCast<SceneGraph::HierarchyNode>( (*itr)->GetHitObject() ); if ( s_ObjectSnap ) { Vector4 v = node->GetTransform()->GetGlobalTransform().t; position.x = v.x; position.y = v.y; position.z = v.z; } else { position = (*itr)->GetIntersection(); } set = true; break; } } } if (!set) { // place the object on the camera plane m_Scene->GetViewport()->GetCamera()->ViewportToPlaneVertex( (float32_t)x, (float32_t)y, SceneGraph::CreateTool::s_PlaneSnap, position); } }
bool CurveEditTool::MouseDown( const MouseButtonInput& e ) { bool success = true; if ( GetEditMode() == CurveEditModes::Modify ) { success = m_ControlPointManipulator->MouseDown( e ); } else { Curve* curve = NULL; { FrustumLinePickVisitor pick (m_Scene->GetViewport()->GetCamera(), e.GetPosition().x, e.GetPosition().y); m_Scene->Pick( &pick ); V_PickHitSmartPtr sorted; PickHit::Sort(m_Scene->GetViewport()->GetCamera(), pick.GetHits(), sorted, PickSortTypes::Intersection); for ( V_PickHitSmartPtr::const_iterator itr = sorted.begin(), end = sorted.end(); itr != end; ++itr ) { if ( curve = Reflect::SafeCast<Curve>( (*itr)->GetHitObject() ) ) { break; } } } if ( !curve || !m_Scene->IsEditable() ) { return false; } LinePickVisitor pick (m_Scene->GetViewport()->GetCamera(), e.GetPosition().x, e.GetPosition().y); switch ( GetEditMode() ) { case CurveEditModes::Insert: { std::pair<uint32_t, uint32_t> points; if ( !curve->ClosestControlPoints( &pick, points ) ) { return false; } CurveControlPoint* p0 = curve->GetControlPointByIndex( points.first ); CurveControlPoint* p1 = curve->GetControlPointByIndex( points.second ); Vector3 a( p0->GetPosition() ); Vector3 b( p1->GetPosition() ); Vector3 p; if ( curve->GetCurveType() == CurveType::Linear ) { float mu; if ( !pick.GetPickSpaceLine().IntersectsSegment( a, b, -1.0f, &mu ) ) { return false; } p = a * ( 1.0f - mu ) + b * mu; } else { p = ( a + b ) * 0.5f; } uint32_t index = points.first > points.second ? points.first : points.second; CurveControlPointPtr point = new CurveControlPoint(); point->SetOwner( curve->GetOwner() ); point->Initialize(); curve->GetOwner()->Push( curve->InsertControlPointAtIndex( index, point ) ); break; } case CurveEditModes::Remove: { int32_t index = curve->ClosestControlPoint( &pick ); if ( index < 0 ) { return false; } curve->GetOwner()->Push( curve->RemoveControlPointAtIndex( index ) ); break; } } curve->Dirty(); m_Scene->Execute( false ); } return success || Base::MouseDown( e ); }