Example #1
0
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;
}
Example #4
0
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;
}