void KX_FontObject::UpdateBuckets() { // Update datas and add mesh slot to be rendered only if the object is not culled. if (m_bVisible && m_meshUser) { if (m_pSGNode->IsDirty()) { GetOpenGLMatrix(); } // Allow for some logic brick control if (GetProperty("Text")) { m_text = split_string(GetProperty("Text")->GetText()); } // update the animated color GetObjectColor().getValue(m_color); // Font Objects don't use the glsl shader, this color management code is copied from gpu_shader_material.glsl float color[4]; if (m_do_color_management) { linearrgb_to_srgb_v4(color, m_color); } else { copy_v4_v4(color, m_color); } // HARDCODED MULTIPLICATION FACTOR - this will affect the render resolution directly const float RES = BGE_FONT_RES * m_resolution; const float size = m_fsize * NodeGetWorldScaling()[0] * RES; const float aspect = m_fsize / size; // Account for offset MT_Vector3 offset = NodeGetWorldOrientation() * m_offset * NodeGetWorldScaling(); // Orient the spacing vector MT_Vector3 spacing = NodeGetWorldOrientation() * MT_Vector3(0.0f, m_fsize * m_line_spacing, 0.0f) * NodeGetWorldScaling()[1]; RAS_TextUser *textUser = (RAS_TextUser *)m_meshUser; textUser->SetColor(MT_Vector4(color)); textUser->SetFrontFace(!m_bIsNegativeScaling); textUser->SetFontId(m_fontid); textUser->SetSize(size); textUser->SetDpi(m_dpi); textUser->SetAspect(aspect); textUser->SetOffset(offset); textUser->SetSpacing(spacing); textUser->SetTexts(m_text); textUser->ActivateMeshSlots(); } }
MT_Point3 KX_NavMeshObject::TransformToWorldCoords(const MT_Point3& lpos) { MT_Matrix3x3 orientation = NodeGetWorldOrientation(); const MT_Vector3& scaling = NodeGetWorldScaling(); orientation.scale(scaling[0], scaling[1], scaling[2]); MT_Transform worldtr(NodeGetWorldPosition(), orientation); MT_Point3 wpos = worldtr(lpos); return wpos; }
MT_Point3 KX_NavMeshObject::TransformToLocalCoords(const MT_Point3& wpos) { MT_Matrix3x3 orientation = NodeGetWorldOrientation(); const MT_Vector3& scaling = NodeGetWorldScaling(); orientation.scale(scaling[0], scaling[1], scaling[2]); MT_Transform worldtr(NodeGetWorldPosition(), orientation); MT_Transform invworldtr; invworldtr.invert(worldtr); MT_Point3 lpos = invworldtr(wpos); return lpos; }
void KX_Camera::ExtractFrustumSphere() { if (m_set_frustum_center) return; // compute sphere for the general case and not only symmetric frustum: // the mirror code in ImageRender can use very asymmetric frustum. // We will put the sphere center on the line that goes from origin to the center of the far clipping plane // This is the optimal position if the frustum is symmetric or very asymmetric and probably close // to optimal for the general case. The sphere center position is computed so that the distance to // the near and far extreme frustum points are equal. // get the transformation matrix from device coordinate to camera coordinate MT_Matrix4x4 clip_camcs_matrix = m_projection_matrix; clip_camcs_matrix.invert(); if (m_projection_matrix[3][3] == MT_Scalar(0.0)) { // frustrum projection // detect which of the corner of the far clipping plane is the farthest to the origin MT_Vector4 nfar; // far point in device normalized coordinate MT_Point3 farpoint; // most extreme far point in camera coordinate MT_Point3 nearpoint;// most extreme near point in camera coordinate MT_Point3 farcenter(0.0, 0.0, 0.0);// center of far cliping plane in camera coordinate MT_Scalar F=-1.0, N; // square distance of far and near point to origin MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0 MT_Scalar e, s; // far and near clipping distance (<0) MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance MT_Scalar z; // projection of sphere center on z axis (<0) // tmp value MT_Vector4 npoint(1.0, 1.0, 1.0, 1.0); MT_Vector4 hpoint; MT_Point3 point; MT_Scalar len; for (int i=0; i<4; i++) { hpoint = clip_camcs_matrix*npoint; point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]); len = point.dot(point); if (len > F) { nfar = npoint; farpoint = point; F = len; } // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane len = npoint[0]; npoint[0] = -npoint[1]; npoint[1] = len; farcenter += point; } // the far center is the average of the far clipping points farcenter *= 0.25; // the extreme near point is the opposite point on the near clipping plane nfar.setValue(-nfar[0], -nfar[1], -1.0, 1.0); nfar = clip_camcs_matrix*nfar; nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]); // this is a frustrum projection N = nearpoint.dot(nearpoint); e = farpoint[2]; s = nearpoint[2]; // projection on XY plane for distance to axis computation MT_Point2 farxy(farpoint[0], farpoint[1]); // f is forced positive by construction f = farxy.length(); // get corresponding point on the near plane farxy *= s/e; // this formula preserve the sign of n n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length(); c = MT_Point2(farcenter[0], farcenter[1]).length()/e; // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case z = (F-N)/(2.0*(e-s+c*(f-n))); m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z); m_frustum_radius = m_frustum_center.distance(farpoint); } else { // orthographic projection // The most extreme points on the near and far plane. (normalized device coords) MT_Vector4 hnear(1.0, 1.0, 1.0, 1.0), hfar(-1.0, -1.0, -1.0, 1.0); // Transform to hom camera local space hnear = clip_camcs_matrix*hnear; hfar = clip_camcs_matrix*hfar; // Tranform to 3d camera local space. MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]); MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]); // just use mediant point m_frustum_center = (farpoint + nearpoint)*0.5; m_frustum_radius = m_frustum_center.distance(farpoint); } // Transform to world space. m_frustum_center = GetCameraToWorld()(m_frustum_center); m_frustum_radius /= fabs(NodeGetWorldScaling()[NodeGetWorldScaling().closestAxis()]); m_set_frustum_center = true; }