| 290 | } |
| 291 | |
| 292 | Result CameraWorldToScreen(HRenderContext render_context, HRenderCamera camera_handle, const dmVMath::Vector3& world, dmVMath::Vector3* out_screen) |
| 293 | { |
| 294 | RenderCamera* camera = render_context->m_RenderCameras.Get(camera_handle); |
| 295 | |
| 296 | // Project world to clip space |
| 297 | dmVMath::Vector4 world4(world.getX(), world.getY(), world.getZ(), 1.0f); |
| 298 | dmVMath::Vector4 clip = camera->m_ViewProjection * world4; |
| 299 | float w = clip.getW(); |
| 300 | if (w > -EPS && w < EPS) |
| 301 | { |
| 302 | return RESULT_INVALID_PARAMETER; |
| 303 | } |
| 304 | float inv_w = 1.0f / w; |
| 305 | float x_ndc = clip.getX() * inv_w; |
| 306 | float y_ndc = clip.getY() * inv_w; |
| 307 | |
| 308 | // Window size |
| 309 | dmGraphics::HContext gc = GetGraphicsContext(render_context); |
| 310 | float win_w = (float) dmGraphics::GetWindowWidth(gc); |
| 311 | float win_h = (float) dmGraphics::GetWindowHeight(gc); |
| 312 | if (win_w <= 0.0f) |
| 313 | { |
| 314 | win_w = 1.0f; |
| 315 | } |
| 316 | if (win_h <= 0.0f) |
| 317 | { |
| 318 | win_h = 1.0f; |
| 319 | } |
| 320 | |
| 321 | // Viewport mapping (Normalized Device Coordinates -> screen pixels) |
| 322 | const dmVMath::Vector4& vp = camera->m_Data.m_Viewport; |
| 323 | float vx = vp.getX() * win_w; |
| 324 | float vy = vp.getY() * win_h; |
| 325 | float vw = vp.getZ() * win_w; |
| 326 | float vh = vp.getW() * win_h; |
| 327 | if (vw <= 0.0f || vh <= 0.0f) |
| 328 | { |
| 329 | vx = 0.0f; vy = 0.0f; vw = win_w; vh = win_h; |
| 330 | } |
| 331 | |
| 332 | float sx = vx + (x_ndc + 1.0f) * 0.5f * vw; |
| 333 | float sy = vy + (y_ndc + 1.0f) * 0.5f * vh; |
| 334 | |
| 335 | // View depth along camera forward |
| 336 | dmVMath::Vector3 forward = dmVMath::Rotate(camera->m_LastRotation, dmVMath::Vector3(0.0f, 0.0f, -1.0f)); |
| 337 | forward = dmVMath::Normalize(forward); |
| 338 | dmVMath::Point3 world_p(world.getX(), world.getY(), world.getZ()); |
| 339 | float z_view = dmVMath::Dot(world_p - camera->m_LastPosition, forward); |
| 340 | |
| 341 | *out_screen = dmVMath::Vector3(sx, sy, z_view); |
| 342 | return RESULT_OK; |
| 343 | } |
| 344 | |
| 345 | // render_private.h |
| 346 | RenderCamera* GetRenderCameraByUrl(HRenderContext render_context, const dmMessage::URL& camera_url) |
no test coverage detected