float Camera::GetDistance(const Vector3& worldPos) const { if (!orthographic_) { const Vector3& cameraPos = node_ ? node_->GetWorldPosition() : Vector3::ZERO; return (worldPos - cameraPos).Length(); } else return Abs((GetInverseWorldTransform() * worldPos).z_); }
float Camera::GetDistanceSquared(const Vector3& worldPos) const { if (!orthographic_) { const Vector3& cameraPos = node_ ? node_->GetWorldPosition() : Vector3::ZERO; return (worldPos - cameraPos).LengthSquared(); } else { float distance = (GetInverseWorldTransform() * worldPos).z_; return distance * distance; } }
Ray Camera::GetScreenRay(float x, float y) { Ray ret; // If projection is invalid, just return a ray pointing forward if (!IsProjectionValid()) { ret.origin_ = node_ ? node_->GetWorldPosition() : Vector3::ZERO; ret.direction_ = GetForwardVector(); return ret; } Matrix4 viewProjInverse = (GetProjection(false) * GetInverseWorldTransform()).Inverse(); // The parameters range from 0.0 to 1.0. Expand to normalized device coordinates (-1.0 to 1.0) & flip Y axis x = 2.0f * x - 1.0f; y = 1.0f - 2.0f * y; Vector3 near(x, y, 0.0f); Vector3 far(x, y, 1.0f); ret.origin_ = viewProjInverse * near; ret.direction_ = ((viewProjInverse * far) - ret.origin_).Normalized(); return ret; }
bool Zone::IsInside(const Vector3& point) const { // Use an oriented bounding box test Vector3 localPoint(GetInverseWorldTransform() * point); return boundingBox_.IsInside(localPoint) != OUTSIDE; }