Beispiel #1
0
void CInventoryItem::PH_Ch_CrPr			()
{
	net_updateData* p					= NetSync();
	//restore recalculated data and get data for interpolation	
	if (!object().CrPr_IsActivated())	return;
	////////////////////////////////////
	CPHSynchronize* pSyncObj			= NULL;
	pSyncObj = object().PHGetSyncItem	(0);
	if (!pSyncObj)						return;
	////////////////////////////////////
	pSyncObj->get_State					(p->CheckState);

	if (!object().H_Parent() && object().getVisible())
	{
		if (p->CheckState.enabled == false && p->RecalculatedState.enabled == true)
		{
			///////////////////////////////////////////////////////////////////
			pSyncObj->set_State			(p->LastState);
			pSyncObj->set_State			(p->RecalculatedState);//, N_A.State.enabled);

			object().PHUnFreeze			();
			///////////////////////////////////////////////////////////////////
			ph_world->Step				();
			///////////////////////////////////////////////////////////////////
			PH_Ch_CrPr					();
			////////////////////////////////////
		};
	};	
};
Beispiel #2
0
void CInventoryItem::PH_A_CrPr		()
{
	net_updateData* p					= NetSync();
	//restore recalculated data and get data for interpolation	
	if (!object().CrPr_IsActivated())	return;
	////////////////////////////////////
	CPHSynchronize* pSyncObj			= NULL;
	pSyncObj = object().PHGetSyncItem	(0);
	if (!pSyncObj)						return;
	////////////////////////////////////
	pSyncObj->get_State					(p->PredictedState);
	////////////////////////////////////
	pSyncObj->set_State					(p->RecalculatedState);
	////////////////////////////////////

	if (!m_flags.test(FInInterpolate)) return;
	////////////////////////////////////
	Fmatrix xformX;
	pSyncObj->cv2obj_Xfrom(p->PredictedState.quaternion, p->PredictedState.position, xformX);

	VERIFY2								(_valid(xformX),*object().cName());
	pSyncObj->cv2obj_Xfrom				(p->PredictedState.quaternion, p->PredictedState.position, xformX);
	
	p->IEndRot.set						(xformX);
	p->IEndPos.set						(xformX.c);
	VERIFY2								(_valid(p->IEndPos),*object().cName());
	/////////////////////////////////////////////////////////////////////////
	CalculateInterpolationParams		();
	///////////////////////////////////////////////////
};
Beispiel #3
0
void CInventoryItem::PH_B_CrPr		()
{
	net_updateData* p		= NetSync();
	//just set last update data for now
	if (object().CrPr_IsActivated()) return;
	if (object().CrPr_GetActivationStep() > ph_world->m_steps_num) return;
	object().CrPr_SetActivated(true);

	///////////////////////////////////////////////
	CPHSynchronize* pSyncObj				= NULL;
	pSyncObj = object().PHGetSyncItem		(0);
	if (!pSyncObj)							return;
	///////////////////////////////////////////////
	pSyncObj->get_State						(p->LastState);
	///////////////////////////////////////////////
	net_update_IItem N_I	= p->NET_IItem.back();

	pSyncObj->set_State						(N_I.State);

	object().PHUnFreeze						();
	///////////////////////////////////////////////
	if (Level().InterpolationDisabled())
	{
		m_flags.set			(FInInterpolation, FALSE);
//		m_bInInterpolation = false;
	};
	///////////////////////////////////////////////
};	
Beispiel #4
0
void CPhysicObject::Interpolate()
{
	net_updatePhData* p = NetSync();
	CPHSynchronize* pSyncObj = this->PHGetSyncItem(0);

	//simple linear interpolation...
	if (!this->H_Parent() &&
		this->getVisible() &&
		this->m_pPhysicsShell &&
		!OnServer() &&
		p->NET_IItem.size())
	{
		SPHNetState newState = p->NET_IItem.front().State;
				
		if (p->NET_IItem.size() >= 2)
		{

			float ret_interpolate = interpolate_states(p->NET_IItem.front(), p->NET_IItem.back(), newState);
			//Msg("Interpolation factor is %0.4f", ret_interpolate);
			//Msg("Current position is: x = %3.3f, y = %3.3f, z = %3.3f", newState.position.x, newState.position.y, newState.position.z);
			if (ret_interpolate >= 1.f)
			{
				p->NET_IItem.pop_front();
				if (m_activated)
				{
					Msg("Deactivating object [%d] after interpolation finish", ID());
					processing_deactivate();
					m_activated = false;
				}
			}
		}
		pSyncObj->set_State(newState);
	}
}
Beispiel #5
0
void CInventoryItem::net_Export			(NET_Packet& P) 
{	
	P.w_float			(m_fCondition);
	P.w_u32				(Level().timeServer());	
	///////////////////////////////////////
	CPHSynchronize* pSyncObj				= NULL;
	SPHNetState	State;
	pSyncObj = object().PHGetSyncItem		(0);
	if (pSyncObj && !object().H_Parent()) 
		pSyncObj->get_State(State);
	else 	
		State.position.set(object().Position());
	///////////////////////////////////////	
	u16 NumItems = object().PHGetSyncItemsNumber();
	if (object().H_Parent())
		NumItems = CSE_ALifeInventoryItem::FLAG_NO_POSITION;
	else
		if (IsGameTypeSingle())
						NumItems = 0;

	P.w_u16					( NumItems		);
	if (NumItems != CSE_ALifeInventoryItem::FLAG_NO_POSITION)
		P.w_vec3			( State.position);

	if (!NumItems || (NumItems == CSE_ALifeInventoryItem::FLAG_NO_POSITION))
		return;
	position_Export(P,State);
};
void CInventoryItem::OnEvent (NET_Packet& P, u16 type)
{
	switch (type)
	{
	case GE_ADDON_ATTACH:
		{
			u16 ItemID;
			P.r_u16			(ItemID);
			CInventoryItem*	 ItemToAttach	= smart_cast<CInventoryItem*>(Level().Objects.net_Find(ItemID));
			if (!ItemToAttach) break;
			Attach(ItemToAttach,true);
		}break;
	case GE_ADDON_DETACH:
		{
			string64			i_name;
			P.r_stringZ			(i_name);
			Detach(i_name, true);
		}break;	
	case GE_CHANGE_POS:
		{
			Fvector p; 
			P.r_vec3(p);
			CPHSynchronize* pSyncObj = NULL;
			pSyncObj = object().PHGetSyncItem(0);
			if (!pSyncObj) return;
			SPHNetState state;
			pSyncObj->get_State(state);
			state.position = p;
			state.previous_position = p;
			pSyncObj->set_State(state);

		}break;
	}
}
Beispiel #7
0
void CInventoryItem::OnEvent (NET_Packet& P, u16 type)
{
	switch (type)
	{
	case GE_ADDON_ATTACH:
		{
			u32 ItemID;
			P.r_u32			(ItemID);
			CInventoryItem*	 ItemToAttach	= smart_cast<CInventoryItem*>(Level().Objects.net_Find(ItemID));
			if (!ItemToAttach) break;
			Attach(ItemToAttach,true);
			CActor* pActor = smart_cast<CActor*>(object().H_Parent());
			if (pActor && pActor->inventory().ActiveItem() == this)
			{
				pActor->inventory().SetPrevActiveSlot(pActor->inventory().GetActiveSlot());
				pActor->inventory().Activate(NO_ACTIVE_SLOT);
				
			}
		}break;
	case GE_ADDON_DETACH:
		{
			string64			i_name;
			P.r_stringZ			(i_name);
			Detach(i_name, true);
			CActor* pActor = smart_cast<CActor*>(object().H_Parent());
			if (pActor && pActor->inventory().ActiveItem() == this)
			{
				pActor->inventory().SetPrevActiveSlot(pActor->inventory().GetActiveSlot());
				pActor->inventory().Activate(NO_ACTIVE_SLOT);
			};
		}break;	
	case GE_CHANGE_POS:
		{
			Fvector p; 
			P.r_vec3(p);
			CPHSynchronize* pSyncObj = NULL;
			pSyncObj = object().PHGetSyncItem(0);
			if (!pSyncObj) return;
			SPHNetState state;
			pSyncObj->get_State(state);
			state.position = p;
			state.previous_position = p;
			pSyncObj->set_State(state);

		}break;
	}
}
Beispiel #8
0
void CPhysicObject::net_Export			(NET_Packet& P) 
{	
	if (this->H_Parent() || IsGameTypeSingle()) 
	{
		P.w_u8				(0);
		return;
	}

	CPHSynchronize* pSyncObj				= NULL;
	SPHNetState								State;
	pSyncObj = this->PHGetSyncItem		(0);

	if (pSyncObj && !this->H_Parent()) 
		pSyncObj->get_State					(State);
	else 	
		State.position.set					(this->Position());


	mask_num_items			num_items;
	num_items.mask			= 0;
	u16						temp = this->PHGetSyncItemsNumber();
	R_ASSERT				(temp < (u16(1) << 5));
	num_items.num_items		= u8(temp);

	if (State.enabled)									num_items.mask |= CSE_ALifeObjectPhysic::inventory_item_state_enabled;
	if (fis_zero(State.angular_vel.square_magnitude()))	num_items.mask |= CSE_ALifeObjectPhysic::inventory_item_angular_null;
	if (fis_zero(State.linear_vel.square_magnitude()))	num_items.mask |= CSE_ALifeObjectPhysic::inventory_item_linear_null;
	//if (m_pPhysicsShell->PPhysicsShellAnimator())		{num_items.mask |= CSE_ALifeObjectPhysic::animated;}

	P.w_u8					(num_items.common);

	/*if (num_items.mask&CSE_ALifeObjectPhysic::animated)
	{
		net_Export_Anim_Params(P);
	}*/
	net_Export_PH_Params(P,State,num_items);
	
	if (PPhysicsShell()->isEnabled())
	{
		P.w_u8(1);	//not freezed
	} else
	{
		P.w_u8(0);  //freezed
	}
};
Beispiel #9
0
void CInventoryItem::PH_I_CrPr		()		// actions & operations between two phisic prediction steps
{
	net_updateData* p					= NetSync();
	//store recalculated data, then we able to restore it after small future prediction
	if (!object().CrPr_IsActivated())	return;
	////////////////////////////////////
	CPHSynchronize* pSyncObj			= NULL;
	pSyncObj = object().PHGetSyncItem	(0);
	if (!pSyncObj)						return;
	////////////////////////////////////
	pSyncObj->get_State					(p->RecalculatedState);
	///////////////////////////////////////////////
	Fmatrix xformX;
	pSyncObj->cv2obj_Xfrom(p->RecalculatedState.quaternion, p->RecalculatedState.position, xformX);

	VERIFY2								(_valid(xformX),*object().cName());
	pSyncObj->cv2obj_Xfrom				(p->RecalculatedState.quaternion, p->RecalculatedState.position, xformX);

	p->IRecRot.set(xformX);
	p->IRecPos.set(xformX.c);
	VERIFY2								(_valid(p->IRecPos),*object().cName());
}; 
Beispiel #10
0
void CInventoryItem::make_Interpolation	()
{
	net_updateData* p		= NetSync();
	p->m_dwILastUpdateTime = Level().timeServer();
	
	if(!object().H_Parent() && object().getVisible() && object().m_pPhysicsShell && m_flags.test(FInInterpolation) ) 
	{

		u32 CurTime = Level().timeServer();
		if (CurTime >= p->m_dwIEndTime) 
		{
			m_flags.set(FInInterpolation, FALSE);

			object().m_pPhysicsShell->NetInterpolationModeOFF();

			CPHSynchronize* pSyncObj		= NULL;
			pSyncObj						= object().PHGetSyncItem(0);
			pSyncObj->set_State				(p->PredictedState);
			Fmatrix xformI;
			pSyncObj->cv2obj_Xfrom			(p->PredictedState.quaternion, p->PredictedState.position, xformI);
			VERIFY2							(_valid(object().renderable.xform),*object().cName());
			object().XFORM().set			(xformI);
			VERIFY2								(_valid(object().renderable.xform),*object().cName());
		}
		else 
		{
			VERIFY			(CurTime <= p->m_dwIEndTime);
			float factor	= float(CurTime - p->m_dwIStartTime)/(p->m_dwIEndTime - p->m_dwIStartTime);
			if (factor > 1) factor = 1.0f;
			else if (factor < 0) factor = 0;

			Fvector IPos;
			Fquaternion IRot;

			float c = factor;
			for (u32 k=0; k<3; k++)
			{
				IPos[k] = c*(c*(c*p->SCoeff[k][0]+p->SCoeff[k][1])+p->SCoeff[k][2])+p->SCoeff[k][3];
			};

			VERIFY2								(_valid(IPos),*object().cName());
			VERIFY			(factor>=0.f && factor<=1.f);
			IRot.slerp(p->IStartRot, p->IEndRot, factor);
			VERIFY2								(_valid(IRot),*object().cName());
			object().XFORM().rotation(IRot);
			VERIFY2								(_valid(object().renderable.xform),*object().cName());
			object().Position().set(IPos);
			VERIFY2								(_valid(object().renderable.xform),*object().cName());
		};
	}
	else
	{
		m_flags.set(FInInterpolation,FALSE);
	};

#ifdef DEBUG
	Fvector iPos = object().Position();

	if (!object().H_Parent() && object().getVisible()) 
	{
		if(m_net_updateData)
			m_net_updateData->LastVisPos.push_back(iPos);
	};
#endif
}
Beispiel #11
0
void CInventoryItem::CalculateInterpolationParams()
{
	net_updateData* p = NetSync();
	p->IStartPos.set(object().Position());
	p->IStartRot.set(object().XFORM());

	Fvector P0, P1, P2, P3;

	CPHSynchronize* pSyncObj = NULL;
	pSyncObj = object().PHGetSyncItem(0);
	
	Fmatrix xformX0, xformX1;	

	if (m_flags.test(FInInterpolation))
	{
		u32 CurTime = Level().timeServer();
		float factor	= float(CurTime - p->m_dwIStartTime)/(p->m_dwIEndTime - p->m_dwIStartTime);
		if (factor > 1.0f) factor = 1.0f;

		float c = factor;
		for (u32 k=0; k<3; k++)
		{
			P0[k] = c*(c*(c*p->SCoeff[k][0]+p->SCoeff[k][1])+p->SCoeff[k][2])+p->SCoeff[k][3];
			P1[k] = (c*c*p->SCoeff[k][0]*3+c*p->SCoeff[k][1]*2+p->SCoeff[k][2])/3; // сокрость из формулы в 3 раза превышает скорость при расчете коэффициентов !!!!
		};
		P0.set(p->IStartPos);
		P1.add(p->IStartPos);
	}	
	else
	{
		P0 = p->IStartPos;

		if (p->LastState.linear_vel.x == 0 && 
			p->LastState.linear_vel.y == 0 && 
			p->LastState.linear_vel.z == 0)
		{
			pSyncObj->cv2obj_Xfrom(p->RecalculatedState.previous_quaternion, p->RecalculatedState.previous_position, xformX0);
			pSyncObj->cv2obj_Xfrom(p->RecalculatedState.quaternion, p->RecalculatedState.position, xformX1);
		}
		else
		{
			pSyncObj->cv2obj_Xfrom(p->LastState.previous_quaternion, p->LastState.previous_position, xformX0);
			pSyncObj->cv2obj_Xfrom(p->LastState.quaternion, p->LastState.position, xformX1);
		};

		P1.sub(xformX1.c, xformX0.c);
		P1.add(p->IStartPos);
	}

	P2.sub(p->PredictedState.position, p->PredictedState.linear_vel);
	pSyncObj->cv2obj_Xfrom(p->PredictedState.quaternion, P2, xformX0);
	P2.set(xformX0.c);

	pSyncObj->cv2obj_Xfrom(p->PredictedState.quaternion, p->PredictedState.position, xformX1);
	P3.set(xformX1.c);
	/////////////////////////////////////////////////////////////////////////////
	Fvector TotalPath;
	TotalPath.sub(P3, P0);
	float TotalLen = TotalPath.magnitude();
	
	SPHNetState	State0 = (p->NET_IItem.back()).State;
	SPHNetState	State1 = p->PredictedState;

	float lV0 = State0.linear_vel.magnitude();
	float lV1 = State1.linear_vel.magnitude();

	u32		ConstTime = u32((fixed_step - ph_world->m_frame_time)*1000)+ Level().GetInterpolationSteps()*u32(fixed_step*1000);
	
	p->m_dwIStartTime = p->m_dwILastUpdateTime;

	if (( lV0 + lV1) > 0.000001 && g_cl_lvInterp == 0)
	{
		u32		CulcTime = iCeil(TotalLen*2000/( lV0 + lV1));
		p->m_dwIEndTime = p->m_dwIStartTime + min(CulcTime, ConstTime);
	}
	else
		p->m_dwIEndTime = p->m_dwIStartTime + ConstTime;
	/////////////////////////////////////////////////////////////////////////////
	Fvector V0, V1;
	V0.sub(P1, P0);
	V1.sub(P3, P2);
	lV0 = V0.magnitude();
	lV1 = V1.magnitude();

	if (TotalLen != 0)
	{
		if (V0.x != 0 || V0.y != 0 || V0.z != 0)
		{
			if (lV0 > TotalLen/3)
			{
				V0.normalize();
				V0.mul(TotalLen/3);
				P1.add(V0, P0);
			}
		}
		
		if (V1.x != 0 || V1.y != 0 || V1.z != 0)
		{
			if (lV1 > TotalLen/3)
			{
				V1.normalize();
				V1.mul(TotalLen/3);
				P2.sub(P3, V1);
			};
		}
	};
	/////////////////////////////////////////////////////////////////////////////
	for( u32 i =0; i<3; i++)
	{
		p->SCoeff[i][0] = P3[i]	- 3*P2[i] + 3*P1[i] - P0[i];
		p->SCoeff[i][1] = 3*P2[i]	- 6*P1[i] + 3*P0[i];
		p->SCoeff[i][2] = 3*P1[i]	- 3*P0[i];
		p->SCoeff[i][3] = P0[i];
	};
	/////////////////////////////////////////////////////////////////////////////
	m_flags.set	(FInInterpolation, TRUE);

	if (object().m_pPhysicsShell) object().m_pPhysicsShell->NetInterpolationModeON();

};
Beispiel #12
0
void CInventoryItem::net_Export			(NET_Packet& P) 
{	
	//copy from CPhysicObject
	if (object().H_Parent() || IsGameTypeSingle()) 
	{
		P.w_u8				(0);
		return;
	}

	CPHSynchronize* pSyncObj				= NULL;
	SPHNetState								State;
	pSyncObj = object().PHGetSyncItem		(0);

	if (pSyncObj && !object().H_Parent()) 
		pSyncObj->get_State					(State);
	else 	
		State.position.set					(object().Position());


	mask_inv_num_items			num_items;
	num_items.mask			= 0;
	u16						temp = object().PHGetSyncItemsNumber();
	R_ASSERT				(temp < (u16(1) << 5));
	num_items.num_items		= u8(temp);

	if (State.enabled)									num_items.mask |= CSE_ALifeInventoryItem::inventory_item_state_enabled;
	if (fis_zero(State.angular_vel.square_magnitude()))	num_items.mask |= CSE_ALifeInventoryItem::inventory_item_angular_null;
	if (fis_zero(State.linear_vel.square_magnitude()))	num_items.mask |= CSE_ALifeInventoryItem::inventory_item_linear_null;
	//if (m_pPhysicsShell->PPhysicsShellAnimator())		{num_items.mask |= CSE_ALifeObjectPhysic::animated;}

	P.w_u8					(num_items.common);
	if (!num_items.common)
	{
#ifdef DEBUG
		Msg("--- Number of sync items of inv item object is 0");
#endif // #ifdef DEBUG
		return;
	}

	/*if (num_items.mask&CSE_ALifeObjectPhysic::animated)
	{
		net_Export_Anim_Params(P);
	}*/
	net_Export_PH_Params(P,State,num_items);
	
	if (object().PPhysicsShell() && object().PPhysicsShell()->isEnabled())
	{
		P.w_u8(1);	//not freezed
	} else
	{
		P.w_u8(0);  //freezed
	}

	/*if (object().H_Parent() || IsGameTypeSingle()) 
	{
		P.w_u8				(0);
		return;
	}
	CPHSynchronize* pSyncObj				= NULL;
	SPHNetState								State;
	pSyncObj = object().PHGetSyncItem		(0);

	if (pSyncObj && !object().H_Parent()) 
		pSyncObj->get_State					(State);
	else 	
		State.position.set					(object().Position());


	mask_num_items			num_items;
	num_items.mask			= 0;
	u16						temp = object().PHGetSyncItemsNumber();
	R_ASSERT				(temp < (u16(1) << 5));
	num_items.num_items		= u8(temp);

	if (State.enabled)									num_items.mask |= CSE_ALifeInventoryItem::inventory_item_state_enabled;
	if (fis_zero(State.angular_vel.square_magnitude()))	num_items.mask |= CSE_ALifeInventoryItem::inventory_item_angular_null;
	if (fis_zero(State.linear_vel.square_magnitude()))	num_items.mask |= CSE_ALifeInventoryItem::inventory_item_linear_null;

	P.w_u8					(num_items.common);

	P.w_vec3				(State.position);

	float					magnitude = _sqrt(State.quaternion.magnitude());
	if (fis_zero(magnitude)) {
		magnitude			= 1;
		State.quaternion.x	= 0.f;
		State.quaternion.y	= 0.f;
		State.quaternion.z	= 1.f;
		State.quaternion.w	= 0.f;
	}
	else {
		float				invert_magnitude = 1.f/magnitude;
		
		State.quaternion.x	*= invert_magnitude;
		State.quaternion.y	*= invert_magnitude;
		State.quaternion.z	*= invert_magnitude;
		State.quaternion.w	*= invert_magnitude;

		clamp				(State.quaternion.x, -1.f, 1.f);
		clamp				(State.quaternion.y, -1.f, 1.f);
		clamp				(State.quaternion.z, -1.f, 1.f);
		clamp				(State.quaternion.w, -1.f, 1.f);
	}

	P.w_float_q8			(State.quaternion.x, -1.f, 1.f);
	P.w_float_q8			(State.quaternion.y, -1.f, 1.f);
	P.w_float_q8			(State.quaternion.z, -1.f, 1.f);
	P.w_float_q8			(State.quaternion.w, -1.f, 1.f);

	if (!(num_items.mask & CSE_ALifeInventoryItem::inventory_item_angular_null)) {
		clamp				(State.angular_vel.x,0.f,10.f*PI_MUL_2);
		clamp				(State.angular_vel.y,0.f,10.f*PI_MUL_2);
		clamp				(State.angular_vel.z,0.f,10.f*PI_MUL_2);

		P.w_float_q8		(State.angular_vel.x,0.f,10.f*PI_MUL_2);
		P.w_float_q8		(State.angular_vel.y,0.f,10.f*PI_MUL_2);
		P.w_float_q8		(State.angular_vel.z,0.f,10.f*PI_MUL_2);
	}

	if (!(num_items.mask & CSE_ALifeInventoryItem::inventory_item_linear_null)) {
		clamp				(State.linear_vel.x,-32.f,32.f);
		clamp				(State.linear_vel.y,-32.f,32.f);
		clamp				(State.linear_vel.z,-32.f,32.f);

		P.w_float_q8		(State.linear_vel.x,-32.f,32.f);
		P.w_float_q8		(State.linear_vel.y,-32.f,32.f);
		P.w_float_q8		(State.linear_vel.z,-32.f,32.f);
	}

	if (object().PPhysicsShell() && object().PPhysicsShell()->isEnabled())
	{
		P.w_u8(1);	//not freezed
	} else
	{
		P.w_u8(0);  //freezed
	}*/
};
Beispiel #13
0
void CInventoryItem::net_Export			(NET_Packet& P) 
{	
	if (object().H_Parent() || IsGameTypeSingle()) 
	{
		P.w_u8				(0);
		return;
	}
	CPHSynchronize* pSyncObj				= NULL;
	SPHNetState								State;
	pSyncObj = object().PHGetSyncItem		(0);

	if (pSyncObj && !object().H_Parent()) 
		pSyncObj->get_State					(State);
	else 	
		State.position.set					(object().Position());


	mask_num_items			num_items;
	num_items.mask			= 0;
	u16						temp = bone_count_to_synchronize();

	R_ASSERT				(temp < (u16(1) << 5));
	num_items.num_items		= u8(temp);

	if (State.enabled)									num_items.mask |= CSE_ALifeInventoryItem::inventory_item_state_enabled;
	if (fis_zero(State.angular_vel.square_magnitude()))	num_items.mask |= CSE_ALifeInventoryItem::inventory_item_angular_null;
	if (fis_zero(State.linear_vel.square_magnitude()))	num_items.mask |= CSE_ALifeInventoryItem::inventory_item_linear_null;

	P.w_u8					(num_items.common);

	P.w_vec3				(State.position);

	float					magnitude = _sqrt(State.quaternion.magnitude());
	if (fis_zero(magnitude)) {
		magnitude			= 1;
		State.quaternion.x	= 0.f;
		State.quaternion.y	= 0.f;
		State.quaternion.z	= 1.f;
		State.quaternion.w	= 0.f;
	}
	else {
		float				invert_magnitude = 1.f/magnitude;
		
		State.quaternion.x	*= invert_magnitude;
		State.quaternion.y	*= invert_magnitude;
		State.quaternion.z	*= invert_magnitude;
		State.quaternion.w	*= invert_magnitude;

		clamp				(State.quaternion.x,0.f,1.f);
		clamp				(State.quaternion.y,0.f,1.f);
		clamp				(State.quaternion.z,0.f,1.f);
		clamp				(State.quaternion.w,0.f,1.f);
	}

	P.w_float_q8			(State.quaternion.x,0.f,1.f);
	P.w_float_q8			(State.quaternion.y,0.f,1.f);
	P.w_float_q8			(State.quaternion.z,0.f,1.f);
	P.w_float_q8			(State.quaternion.w,0.f,1.f);

	if (!(num_items.mask & CSE_ALifeInventoryItem::inventory_item_angular_null)) {
		clamp				(State.angular_vel.x,0.f,10.f*PI_MUL_2);
		clamp				(State.angular_vel.y,0.f,10.f*PI_MUL_2);
		clamp				(State.angular_vel.z,0.f,10.f*PI_MUL_2);

		P.w_float_q8		(State.angular_vel.x,0.f,10.f*PI_MUL_2);
		P.w_float_q8		(State.angular_vel.y,0.f,10.f*PI_MUL_2);
		P.w_float_q8		(State.angular_vel.z,0.f,10.f*PI_MUL_2);
	}

	if (!(num_items.mask & CSE_ALifeInventoryItem::inventory_item_linear_null)) {
		clamp				(State.linear_vel.x,-32.f,32.f);
		clamp				(State.linear_vel.y,-32.f,32.f);
		clamp				(State.linear_vel.z,-32.f,32.f);

		P.w_float_q8		(State.linear_vel.x,-32.f,32.f);
		P.w_float_q8		(State.linear_vel.y,-32.f,32.f);
		P.w_float_q8		(State.linear_vel.z,-32.f,32.f);
	}
};