Получить SCNVector3 от CGPoint

Я пытаюсь получить SCNVector3 от CGPoint. Я использую распознаватель жестов, чтобы получить местоположение касания (как CGPoint).

Проблема в том, что касание не всегда касается чего-либо, когда я нажимаю на тест, потому что не всегда происходит касание объекта. (Коснитесь пустого места, чтобы переместить ваш корабль в это пустое место).

Другой вопрос переполнения стека, который я нашел, использует SCNHitTestResult, чтобы получить worldCoordinates но это не работает для меня.

Кто-нибудь знает, как это найти? Учитывая, что я знаю координату z, конечно. Корабли, которые движутся, всегда движутся с позицией z, равной 1.

Мне нужны worldCoordinates, чтобы иметь возможность использовать действия, которые перемещают SCNNode в точку касания, которая имеет CGPoint. Спасибо!

1 ответ

Итак, вы хотите превратить точку в пространстве вида в точку в пространстве сцены? Выгода в том, что пространство сцены имеет третье измерение, а пространство просмотра - нет. Вы используете SCNView (или другие методы визуализации) projectPoint а также unprojectPoint преобразовать между пространством сцены, которое является 3D, и пространством просмотра, которое... также 3D? Да - два измерения точек пикселей экрана и одно с нормализованной глубиной: координата z равна 0 для точек на ближней плоскости отсечения и 1 для точек на дальней плоскости отсечения.

В любом случае, у вас есть полезное ограничение в том, что вы хотите отобразить точки пространства просмотра на определенной плоскости (z=1) в пространстве сцены. У вас есть еще более полезное ограничение, если пространство вашей сцены ориентировано так, чтобы указанная плоскость была перпендикулярна направлению обзора - т.е. камера направлена ​​прямо в направлении +z или -z.

Если вы хотите отобразить точку пространства обзора на определенную глубину пространства сцены, вам нужно знать, какова глубина пространства обзора для этой плоскости. использование projectPoint для этого:

SCNVector3 projectedPlaneCenter = [view projectPoint:planeNode.position];
float projectedDepth = projectedPlaneCenter.z;

Теперь держитесь за это, и вы можете использовать его всякий раз, когда вам нужно отобразить местоположение касания на эту плоскость:

CGPoint vp = [recognizer locationInView:view];
SCNVector3 vpWithDepth = SCNVector3Make(vp.x, vp.y, projectedDepth);
SCNVector3 scenePoint = [view unprojectPoint:vpWithDepth];

Если ваша сцена не ориентирована с осью Z, параллельной камере, это немного сложнее - вы должны работать там, где ваши z=1 Плоскость является независимой для любой обрабатываемой точки обзора. В этом случае вам может быть проще добавить невидимое SCNPlane к вашей сцене и использовать hitTest / worldCoordinates метод, чтобы найти точки на этой плоскости.

Другие вопросы по тегам