Vector3f TrackballManipulator::CursorToSpherePos()
{
    // Get the renderer.
    Renderer* renderer = GraphicSubsystem::Instance()->GetRenderer();
    GD_ASSERT(renderer);

    mEditor->GetMainView()->MakeCurrent();

     // Get the camera.
    Camera* camera = mEditor->GetWorldManager().GetCurrentCamera();
    Float farViewDistance = camera->GetFarView();

    // Get the mouse position.
    Int32 x, y;
    InputSubsystem::GetMouse().GetPos(x, y);
    QPoint widgetPos = mEditor->GetMainView()->mapFromGlobal(QPoint(x, y));

    Int32    viewport[4];
    renderer->GetViewport(viewport);
    
    Vector2f screenRay( widgetPos.x(), viewport[3] - widgetPos.y() );

    // Get the vector from the mouse positions.
    Vector3f worldRayStart = camera->GetPosition();
    Vector3f worldRayEnd   = renderer->ScreenToWorld( screenRay ) - camera->GetPosition();

    worldRayEnd.Normalize();
    worldRayEnd *= farViewDistance;

    Vector3f onSphere = SphereLineIntersection( worldRayStart, worldRayEnd, mBallPos, 1 );

    return (onSphere-mBallPos).GetNormalized() + mBallPos;
}
Entity* WorldManager::DoSelectionTest( const Vector2f& pSelectionPoint )
{
    Int32     viewport[4];
    Renderer* renderer = GraphicSubsystem::Instance()->GetRenderer();
    renderer->GetViewport(viewport);

    Vector3f screenRay( pSelectionPoint.x, viewport[3] - pSelectionPoint.y - 1, 0 );
    Vector3f worldRay = renderer->ScreenToWorld( screenRay );

    // Get the vector from the mouse positions.
    Vector3f testOrigin = worldRay;    
    Vector3f testDir = worldRay - GetCurrentCamera()->GetPosition();
    testDir.Normalize();

    return LineTrace( testOrigin, testDir );
}
Exemple #3
0
	Intersection WorldViewer::pixelIntersect(const int2 &screen_pos, const FindFilter &filter) const {
		Intersection out;
		FBox out_bbox;

		if(filter.flags() & Flags::tile) {
			const TileMap &tile_map = m_world->tileMap();
			vector<int> inds;
			tile_map.findAll(inds, IRect(screen_pos, screen_pos + int2(1, 1)), filter.flags() | Flags::visible);

			for(int i = 0; i < (int)inds.size(); i++) {
				const auto &desc = tile_map[inds[i]];
				
				FBox bbox = desc.bbox;
				
				if(out.empty() || drawingOrder(bbox, out_bbox) == 1)
					if(desc.ptr->testPixel(screen_pos - worldToScreen((int3)bbox.min))) {
						out = ObjectRef(inds[i], false);
						out_bbox = bbox;
					}
			}
		}

		if(filter.flags() & Flags::entity) {
			int ignore_index = m_world->filterIgnoreIndex(filter);

			for(int n = 0; n < (int)m_entities.size(); n++) {
				const Entity *entity = refEntity(n);
				if(!entity || !m_occluder_config.isVisible(m_entities[n].occluder_id) || !Flags::test(entity->flags(), filter.flags()) || n == ignore_index)
					continue;
				if(!entity->testPixel(screen_pos))
					continue;
				FBox bbox = entity->boundingBox();

				//TODO: check this
				if(out.empty() || drawingOrder(bbox, out_bbox) == 1) {
					out = ObjectRef(n, true);
					out_bbox = bbox;
				}
			}
		}

		if(out.empty())
			return Intersection();
		return Intersection(out, intersection(screenRay(screen_pos), out_bbox));
	}
	void EntitiesEditor::computeCursor(int2 start, int2 end, bool floor_mode) {
		float2 height_off = worldToScreen(int3(0, 0, 0));

		start += m_view.pos();
		  end += m_view.pos();

		Ray ray = screenRay(start);

		Flags::Type flags = Flags::all;
		if(floor_mode)
			flags = flags & ~(Flags::wall_tile | Flags::object_tile);

		auto isect = m_tile_map.trace(ray, -1, flags | Flags::visible);
		float3 pos = isect.first == -1? (float3)asXZ(screenToWorld(start)) : ray.at(isect.second);

		m_cursor_pos = (float3)round(pos);
		m_selection = IRect(min(start, end), max(start, end));
	}