Hi! I need to project 3d position of a GameObject in scene to screenspace (canvas). I’m checking the camera component inside needle engine, but it doesn’t have a public way to acces the underlying three.js camera. Also it has a screenPointToRay function, but i think this would be an ideal place to add a function to do this.
So the question is, what is the needle way of projecting a 3D vector into a 2D one (that coincides with the canvas)?
Hello whtw4thewin! To convert a 3D position of a GameObject into screen space using Needle Engine, you’ll typically use the Three.js camera’s capabilities along with a bit of additional math to get the position in pixel coordinates.
Here’s a step-by-step approach to achieve this:
- Get the 3D position of the GameObject in world space.
- Use Three.js Camera to project the 3D position onto the 2D screen space.
- Convert the normalized device coordinates to pixel coordinates suitable for your canvas.
Here’s an implementation in Needle Engine using three.js to achieve the above:
import { Vector3, Vector2, Camera } from "@needle-tools/engine";
// Assuming 'camera' is the instance of your Needle Engine camera
function project3DTo2D(position3D, camera) {
// Create a new Vector3 for the 3D position
const vector = new Vector3(position3D.x, position3D.y, position3D.z);
// Project the Vector3 using the camera
vector.project(camera);
// Convert normalized device coordinates to 2D screen coordinates
const widthHalf = 0.5 * canvasWidth; // Assuming you have canvasWidth
const heightHalf = 0.5 * canvasHeight; // Assuming you have canvasHeight
const position2D = new Vector2();
position2D.x = (vector.x * widthHalf) + widthHalf;
position2D.y = -(vector.y * heightHalf) + heightHalf; // Y is inverted here
return position2D; // Return 2D coordinates
}
Explanation:
- The
project method transforms the 3D coordinates into normalized device coordinates.
- The subsequent calculation converts these normalized coordinates into pixel coordinates based on the canvas dimensions.
- Remember to replace
canvasWidth and canvasHeight with the actual dimensions of your canvas.
This method is the typical approach in Three.js and should work fine in your Needle Engine context.
If you need further clarification or have specific variables in your project to consider, feel free to share!
3 replies left
thread_WDzyOKpBToJTO05l4wqbdMDl
Reply to this message to continue the conversation
It does have sense, but how do i access to the underlying three.js camera from Needle engine, or a needle Engine component?
Hello whtw4thewin! In Needle Engine, while you may not have direct public access to the underlying Three.js camera, you can often access it through the Camera component associated with your Needle Engine GameObject.
Here’s how you can typically achieve that:
- Get the Camera Component: Use the
getComponent method to obtain the camera instance on the GameObject.
- Access the
Three.js Camera: The Needle Engine camera component wraps around the Three.js camera, allowing you to access its properties and methods.
Here’s an example code snippet:
import { Camera } from "@needle-tools/engine";
// Assume `gameObject` is the GameObject you are working with
const cameraComponent = gameObject.getComponent(Camera);
if (cameraComponent) {
const threeCamera = cameraComponent.getCamera(); // This gets the underlying Three.js camera
const position3D = new Vector3(1, 2, 3); // Example position to project
const position2D = project3DTo2D(position3D, threeCamera);
console.log("Screen Position:", position2D);
} else {
console.error("Camera component not found.");
}
Explanation:
- The
gameObject.getComponent(Camera) retrieves the Needle Engine Camera component.
- The
getCamera() method will give you access to the actual Three.js camera you need for further operations.
If you have a specific GameObject or additional context you’re working with, let me know!
3 replies left
thread_WDzyOKpBToJTO05l4wqbdMDl
Reply to this message to continue the conversation
Hi, you can get the threejs camera from the Camera component via the cam property Camera | Needle Engine
Ahhh i missed that property, thanks!
I’ll mark the first answer as the solution since it is more suitable for the title of the question until i have a proper component to showcase 
There is however another issue, how do i acces needle-canvas? I mean the actual canvas on html, not the canvas component (i assume that it refers to Unity-canvas implementation).
Edit: is it necessary to “manually” search for it on the DOM?
No there is no different implementation - Unity has nothing to do with this.
- Get the
<needle-engine> element via context.domElement
- Get the threejs canvas via
context.renderer.domElement