camera.WorldToScreenPoint() - How to replicate with zSpace camera?

I have an object positioned within a container and aligned to the zSpace viewport and outside of zSpace, I can determine the position of this object using the following:

camera.WorldToScreenPoint(object position), but within the zSpace framework, the camera no longer gets updated, so this method returns nothing.

Is there an equivalent method within the zSpace framework?

Hi DJSegler,

I understand the difficulties regarding a lack of typical camera methods. Its true there is no zCore equivalent currently, but it is in the works for future releases. What I can offer for now is an approach I’ve used in the past to mimic the cameras used internally by zcore.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using zSpace.Core;

public class MimicCams : MonoBehaviour {

	private ZCore core;
	private Camera l_cam;
	private Camera r_cam;
	private GameObject main_cam_obj;

    private static readonly Matrix4x4 s_flipHandednessMap = Matrix4x4.Scale(new Vector4(1.0f, 1.0f, -1.0f));

	void Start () {
		core = GameObject.FindObjectOfType<ZCore>();
		main_cam_obj = core.CurrentCameraObject;

		GameObject l_cam_obj = new GameObject();
		GameObject r_cam_obj = new GameObject();
		l_cam_obj.transform.parent = transform;
		r_cam_obj.transform.parent = transform;
		l_cam_obj.name = "Left Mimc Cam";
		r_cam_obj.name = "Right Mimc Cam";
		l_cam = l_cam_obj.AddComponent<Camera>();
		r_cam = r_cam_obj.AddComponent<Camera>();
		l_cam.enabled = false;
		r_cam.enabled = false;
		l_cam.farClipPlane = 7.5f;
		r_cam.farClipPlane = 7.5f;
	}
	
	void Update () {
		MimicStereoCamera(l_cam, ZCore.Eye.Left);
		MimicStereoCamera(r_cam, ZCore.Eye.Right);
	}

	private void MimicStereoCamera(Camera cam, ZCore.Eye eye){
		cam.projectionMatrix  = core.GetFrustumProjectionMatrix(eye);

		cam.transform.position = core.GetFrustumEyePosition(eye, ZCore.CoordinateSpace.World);

		Matrix4x4 v_mtx = FlipHandedness(core.GetFrustumViewMatrix(eye));
		Matrix4x4 cam_mtx = main_cam_obj.transform.localToWorldMatrix * v_mtx.inverse;
		cam.transform.position = cam_mtx.GetColumn(3);
		cam.transform.rotation =
                    Quaternion.LookRotation(
                        cam_mtx.GetColumn(2),
                        cam_mtx.GetColumn(1));
	}

	private Matrix4x4 FlipHandedness(Matrix4x4 matrix) {
		return s_flipHandednessMap * matrix * s_flipHandednessMap;
	}
}

Attach it to an empty game object in the scene. When run, it will child two new camera objects to itself that represent the same position and frustum transforms of zcore’s internal left and right cameras. If you’re looking for a “center” eye, you can follow the same procedure demonstrated, but use ZCore.Eye.Center

I’m not sure I fully understand what you’re trying to accomplish. This could be an “XY problem”, so if the script doesn’t accomplish what you want, feel free to explain at a higher level what your objective is, and I might offer alternative approaches.

Regards,
Alex S.

Thanks for the quick idea. I’ll certainly check it out, but what I’m after is really to just get the 2D coordinates of an object with respect to the viewport. Lower left of the viewport is 0,0 and I’d like to get the x,y position of a gameobject on the display in pixels with the same viewport coordinate reference. Using Camera. WorldToScreenPoint() works great for that, but it’s not available within the zSpace framework since it hijacks the camera. Maybe I can use your proposed class to have another camera follow zSpace and then try accessing the WorldToScreenPoint() method on that camera.

I’m open to other ideas though if there’s an easier way.

Thanks!

That’s probably as easy as it gets. However, by high level, I’m referring to what you’re trying to accomplish by acquiring 2D coordinates of a 3D object. 3D objects in stereo like this don’t have the same relationship with 2d screen space as they do in more conventional monoscopic displays. Those 2D coordinates are inextricably tied to 3D space at the viewport plane whereas in monoscopic rendering they’re more safely thought of separately. Depending on what those coordinates are used for, there might be better alternatives.