Ejemplo n.º 1
0
MT_Matrix4x4 RAS_OpenGLLight::GetShadowMatrix()
{
	GPULamp *lamp;

	if ((lamp = GetGPULamp()))
		return MT_Matrix4x4(GPU_lamp_dynpersmat(lamp));
	MT_Matrix4x4 mat;
	mat.setIdentity();
	return mat;
}
bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam)
{
	/* All screen handling in the gameengine is done by GL,
	 * specifically the model/view and projection parts. The viewport
	 * part is in the creator. 
	 *
	 * The theory is this:
	 * WCS - world coordinates
	 * -> wcs_camcs_trafo ->
	 * camCS - camera coordinates
	 * -> camcs_clip_trafo ->
	 * clipCS - normalized device coordinates?
	 * -> normview_win_trafo
	 * winCS - window coordinates
	 *
	 * The first two transforms are respectively the model/view and
	 * the projection matrix. These are passed to the rasterizer, and
	 * we store them in the camera for easy access.
	 *
	 * For normalized device coords (xn = x/w, yn = y/w/zw) the
	 * windows coords become (lb = left bottom)
	 *
	 * xwin = [(xn + 1.0) * width]/2 + x_lb
	 * ywin = [(yn + 1.0) * height]/2 + y_lb
	 *
	 * Inverting (blender y is flipped!):
	 *
	 * xn = 2(xwin - x_lb)/width - 1.0
	 * yn = 2(ywin - y_lb)/height - 1.0 
	 *    = 2(height - y_blender - y_lb)/height - 1.0
	 *    = 1.0 - 2(y_blender - y_lb)/height
	 *
	 * */
	 
	
	/* Because we don't want to worry about resize events, camera
	 * changes and all that crap, we just determine this over and
	 * over. Stop whining. We have lots of other calculations to do
	 * here as well. These reads are not the main cost. If there is no
	 * canvas, the test is irrelevant. The 1.0 makes sure the
	 * calculations don't bomb. Maybe we should explicitly guard for
	 * division by 0.0...*/
	
	RAS_Rect area, viewport;
	short m_y_inv = m_kxengine->GetCanvas()->GetHeight()-m_y;
	
	m_kxengine->GetSceneViewport(m_kxscene, cam, area, viewport);
	
	/* Check if the mouse is in the viewport */
	if ((	m_x < viewport.m_x2 &&	// less than right
			m_x > viewport.m_x1 &&	// more than then left
			m_y_inv < viewport.m_y2 &&	// below top
			m_y_inv > viewport.m_y1) == 0)	// above bottom
	{
		return false;
	}

	float height = float(viewport.m_y2 - viewport.m_y1 + 1);
	float width  = float(viewport.m_x2 - viewport.m_x1 + 1);
	
	float x_lb = float(viewport.m_x1);
	float y_lb = float(viewport.m_y1);

	MT_Vector4 frompoint;
	MT_Vector4 topoint;
	
	/* m_y_inv - inverting for a bounds check is only part of it, now make relative to view bounds */
	m_y_inv = (viewport.m_y2 - m_y_inv) + viewport.m_y1;
	
	
	/* There's some strangeness I don't fully get here... These values
	 * _should_ be wrong! - see from point Z values */
	
	
	/*	build the from and to point in normalized device coordinates 
	 *	Normalized device coordinates are [-1,1] in x, y, z
	 *
	 *	The actual z coordinates used don't have to be exact just infront and 
	 *	behind of the near and far clip planes.
	 */ 
	frompoint.setValue(	(2 * (m_x-x_lb) / width) - 1.0,
						1.0 - (2 * (m_y_inv - y_lb) / height),
						-1.0,
						1.0 );
	
	topoint.setValue(	(2 * (m_x-x_lb) / width) - 1.0,
						1.0 - (2 * (m_y_inv-y_lb) / height),
						1.0,
						1.0 );
	
	/* camera to world  */
	MT_Matrix4x4 camcs_wcs_matrix = MT_Matrix4x4(cam->GetCameraToWorld());

	/* badly defined, the first time round.... I wonder why... I might
	 * want to guard against floating point errors here.*/
	MT_Matrix4x4 clip_camcs_matrix = MT_Matrix4x4(cam->GetProjectionMatrix());
	clip_camcs_matrix.invert();

	/* shoot-points: clip to cam to wcs . win to clip was already done.*/
	frompoint = clip_camcs_matrix * frompoint;
	topoint   = clip_camcs_matrix * topoint;
	/* clipstart = - (frompoint[2] / frompoint[3])
	 * clipend = - (topoint[2] / topoint[3]) */
	frompoint = camcs_wcs_matrix * frompoint;
	topoint   = camcs_wcs_matrix * topoint;
	
	/* from hom wcs to 3d wcs: */
	m_prevSourcePoint.setValue(	frompoint[0]/frompoint[3],
								frompoint[1]/frompoint[3],
								frompoint[2]/frompoint[3]); 
	
	m_prevTargetPoint.setValue(	topoint[0]/topoint[3],
								topoint[1]/topoint[3],
								topoint[2]/topoint[3]); 
	
	/* 2. Get the object from PhysicsEnvironment */
	/* Shoot! Beware that the first argument here is an
	 * ignore-object. We don't ignore anything... */
	PHY_IPhysicsController* physics_controller = cam->GetPhysicsController();
	PHY_IPhysicsEnvironment* physics_environment = m_kxscene->GetPhysicsEnvironment();

	// get UV mapping
	KX_RayCast::Callback<KX_MouseFocusSensor> callback(this,physics_controller,NULL,false,true);
	 
	KX_RayCast::RayTest(physics_environment, m_prevSourcePoint, m_prevTargetPoint, callback);
	
	if (m_hitObject)
		return true;
	
	return false;
}
	bool
KX_BoneParentRelation::
UpdateChildCoordinates(
	SG_Spatial * child,
	const SG_Spatial * parent,
	bool& parentUpdated
) {
	BLI_assert(child != NULL);
	
	// This way of accessing child coordinates is a bit cumbersome
	// be nice to have non constant reference access to these values.

	const MT_Vector3 & child_scale = child->GetLocalScale();
	const MT_Vector3 & child_pos = child->GetLocalPosition();
	const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
	// we don't know if the armature has been updated or not, assume yes
	parentUpdated = true;

	// the childs world locations which we will update.
	
	MT_Vector3 child_w_scale;
	MT_Vector3 child_w_pos;
	MT_Matrix3x3 child_w_rotation;
	
	bool valid_parent_transform = false;
	
	if (parent)
	{
		BL_ArmatureObject *armature = (BL_ArmatureObject*)(parent->GetSGClientObject());
		if (armature)
		{
			MT_Matrix4x4 parent_matrix;
			if (armature->GetBoneMatrix(m_bone, parent_matrix))
			{
				// Get the child's transform, and the bone matrix.
				MT_Matrix4x4 child_transform ( 
					MT_Transform(child_pos + MT_Vector3(0.0f, armature->GetBoneLength(m_bone), 0.0f), 
						child_rotation.scaled(
							child_scale[0], 
							child_scale[1], 
							child_scale[2])));
				
				// The child's world transform is parent * child
				parent_matrix = MT_Matrix4x4(parent->GetWorldTransform()) * parent_matrix;
				child_transform = parent_matrix * child_transform;
				
				// Recompute the child transform components from the transform.
				child_w_scale.setValue( 
					MT_Vector3(child_transform[0][0], child_transform[0][1], child_transform[0][2]).length(),
					MT_Vector3(child_transform[1][0], child_transform[1][1], child_transform[1][2]).length(),
					MT_Vector3(child_transform[2][0], child_transform[2][1], child_transform[2][2]).length());
				child_w_rotation.setValue(child_transform[0][0], child_transform[0][1], child_transform[0][2], 
					child_transform[1][0], child_transform[1][1], child_transform[1][2], 
					child_transform[2][0], child_transform[2][1], child_transform[2][2]);
				child_w_rotation.scale(1.0f/child_w_scale[0], 1.0f/child_w_scale[1], 1.0f/child_w_scale[2]);
					
				child_w_pos = MT_Vector3(child_transform[0][3], child_transform[1][3], child_transform[2][3]);
					
				valid_parent_transform = true;
			}
		}
	} 
	
	if (valid_parent_transform)
	{
		child->SetWorldScale(child_w_scale);
		child->SetWorldPosition(child_w_pos);
		child->SetWorldOrientation(child_w_rotation);
	}
	else {
		child->SetWorldFromLocalTransform();
	}
	child->ClearModified();
	// this node must always be updated, so reschedule it for next time
	child->ActivateRecheduleUpdateCallback();
	return valid_parent_transform;
}