예제 #1
0
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);
    }
}
예제 #2
0
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 );
}
예제 #3
0
파일: Pick.cpp 프로젝트: FromPointer/Helium
void PickHit::Sort(Editor::Camera* camera, const V_PickHitSmartPtr& hits, V_PickHitSmartPtr& sorted, PickSortType sortType)
{
	// early out if we have no hits
	if (hits.empty())
		return;

	// get our camera distance
	Vector3 cameraPosition;
	camera->GetPosition(cameraPosition);

	V_SortKey sortKeys;

	// for each hit object
	for ( V_PickHitSmartPtr::const_iterator itr = hits.begin(), end = hits.end(); itr != end; ++itr )
	{
		PickHitPtr hit = *itr;
		Vector3 intersection;
		float32_t pickDistance;

		switch (sortType)
		{
		case PickSortTypes::Intersection:
		case PickSortTypes::Surface:
			{
				if (!hit->HasIntersection())
				{
					continue;
				}

				intersection = hit->GetIntersection();
				pickDistance = hit->GetIntersectionDistance();

				break;
			}

		case PickSortTypes::Vertex:
			{
				if (!hit->HasVertex())
				{
					continue;
				}

				intersection = hit->GetVertex();
				pickDistance = hit->GetVertexDistance();

				break;
			}
		}

		float32_t cameraDistance = (cameraPosition - intersection).LengthSquared();

		sortKeys.push_back( SortKey (hit, cameraDistance, pickDistance) );
	}

	switch ( sortType )
	{
	case PickSortTypes::Intersection:
		{
			std::sort( sortKeys.begin(), sortKeys.end(), &CompareCameraDistance );
			break;
		}

	case PickSortTypes::Surface:
		{
			std::sort( sortKeys.begin(), sortKeys.end(), &ComparePickDistanceThenCameraDistance );
			break;
		}

	case PickSortTypes::Vertex:
		{
			std::sort( sortKeys.begin(), sortKeys.end(), &ComparePickDistance );
			break;
		}

	default:
		{
			HELIUM_BREAK();
			break;
		}
	}

	// clear
	sorted.clear();

	// reserve data for our result
	sorted.reserve(sortKeys.size());

	// dump
	V_SortKey::const_iterator itr = sortKeys.begin();
	V_SortKey::const_iterator end = sortKeys.end();
	for( ;itr != end; ++itr )
	{
		sorted.push_back(itr->m_Hit);
	}
}
예제 #4
0
bool CreateTool::DetermineTranslationAndNormal( PickVisitor& pick, Vector3& t, Vector3& n )
{
	// pick in the world
	PickArgs args ( &pick );
	m_PickWorld.Raise( args );

	bool set = false;
	if ( s_SurfaceSnap || s_ObjectSnap )
	{
		// process results
		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 )
		{
			Editor::HierarchyNode* node = Reflect::SafeCast<Editor::HierarchyNode>( (*itr)->GetHitObject() );

			// don't snap against what we are placing
			if ( node == m_Instance )
			{
				continue;
			}

			// eliminate nodes that are not live when we are live snapping
			if ( s_LiveObjectsOnly && !node->IsLive() )
			{
				continue;
			}

			// don't snap if we are surface snapping with no normal
			if ( s_SurfaceSnap && !(*itr)->HasNormal() )
			{
				continue;
			}

			// don't snap if we don't have an intersection
			if ( !(*itr)->HasIntersection() )
			{
				continue;
			}

			if ( s_ObjectSnap )
			{
				Vector4 v = node->GetTransform()->GetGlobalTransform().t;
				t.x = v.x;
				t.y = v.y;
				t.z = v.z;
				set = true;
			}
			else
			{
				t = (*itr)->GetIntersection();
			}

			if ( s_NormalSnap && (*itr)->HasNormal() )
			{
				n = (*itr)->GetNormal();
			}

			set = true;
			break;
		}
	}

	return set;
}