예제 #1
0
파일: PHSkeleton.cpp 프로젝트: 2asoft/xray
void CPHSkeleton::UnsplitSingle(CPHSkeleton* SO)
{
	//Msg("%o,received has %d,",this,m_unsplited_shels.size());
	if (0==m_unsplited_shels.size())	return;	//. hack
	CPhysicsShellHolder* obj = PPhysicsShellHolder();
	CPhysicsShellHolder* O =SO->PPhysicsShellHolder();
	VERIFY2(m_unsplited_shels.size(),"NO_SHELLS !!");
	VERIFY2(!O->m_pPhysicsShell,"this has shell already!!!");
	CPhysicsShell* newPhysicsShell=m_unsplited_shels.front().first;
	O->m_pPhysicsShell=newPhysicsShell;
	VERIFY(_valid(newPhysicsShell->mXFORM));
	IKinematics *newKinematics=smart_cast<IKinematics*>(O->Visual());
	IKinematics *pKinematics  =smart_cast<IKinematics*>(obj->Visual());

	Flags64 mask0,mask1;
	u16 split_bone=m_unsplited_shels.front().second;
	mask1.assign(pKinematics->LL_GetBonesVisible());//source bones mask
	pKinematics->LL_SetBoneVisible(split_bone,FALSE,TRUE);

	pKinematics->CalculateBones_Invalidate	();
	pKinematics->CalculateBones				(TRUE);

	mask0.assign(pKinematics->LL_GetBonesVisible());//first part mask
	VERIFY2(mask0.flags,"mask0 -Zero");
	mask0.invert();
	mask1.and(mask0.flags);//second part mask


	newKinematics->LL_SetBoneRoot		(split_bone);
	VERIFY2(mask1.flags,"mask1 -Zero");
	newKinematics->LL_SetBonesVisible	(mask1.flags);

	newKinematics->CalculateBones_Invalidate	();
	newKinematics->CalculateBones				(TRUE);

	newPhysicsShell->set_Kinematics(newKinematics);
	VERIFY(_valid(newPhysicsShell->mXFORM));
	newPhysicsShell->ResetCallbacks(split_bone,mask1);
	VERIFY(_valid(newPhysicsShell->mXFORM));

	newPhysicsShell->ObjectInRoot().identity();

	if(!newPhysicsShell->isEnabled())O->processing_deactivate();
	newPhysicsShell->set_PhysicsRefObject(O);
	
	m_unsplited_shels.erase(m_unsplited_shels.begin());
	O->setVisible(TRUE);
	O->setEnabled(TRUE);


	SO->CopySpawnInit		();
	CopySpawnInit			();
	VERIFY3(CheckObjectSize(pKinematics),*(O->cNameVisual()),"Object unsplit whith no size");
	VERIFY3(CheckObjectSize(newKinematics),*(O->cNameVisual()),"Object unsplit whith no size");

}
예제 #2
0
void CPHShellSimpleCreator::CreatePhysicsShell()
{
	CPhysicsShellHolder* owner = smart_cast<CPhysicsShellHolder*>(this); VERIFY(owner);
	if (!owner->Visual()) return;
	
	CKinematics* pKinematics		= smart_cast<CKinematics*>(owner->Visual());
	VERIFY							(pKinematics);

	if(owner->PPhysicsShell())		return;
	owner->PPhysicsShell()			= P_create_Shell();
#ifdef DEBUG
	owner->PPhysicsShell()->dbg_obj=owner;
#endif
	owner->m_pPhysicsShell->build_FromKinematics	(pKinematics,0);

	owner->PPhysicsShell()->set_PhysicsRefObject	(owner);
	//m_pPhysicsShell->SmoothElementsInertia(0.3f);
	owner->PPhysicsShell()->mXFORM.set				(owner->XFORM());
	owner->PPhysicsShell()->SetAirResistance		(0.001f, 0.02f);
}
예제 #3
0
void CPHCollisionDamageReceiver::Init()
{
	CPhysicsShellHolder *sh	=PPhysicsShellHolder	();
	IKinematics			*K	=smart_cast<IKinematics*>(sh->Visual());
	CInifile			*ini=K->LL_UserData();
	if(ini->section_exist("collision_damage"))
	{
		
		CInifile::Sect& data		= ini->r_section("collision_damage");
		for (CInifile::SectCIt I=data.Data.begin(); I!=data.Data.end(); I++){
			const CInifile::Item& item	= *I;
			u16 index				= K->LL_BoneID(*item.first); 
			R_ASSERT3(index != BI_NONE, "Wrong bone name", *item.first);
			BoneInsert(index,float(atof(*item.second)));
			CODEGeom* og= sh->PPhysicsShell()->get_GeomByID(index);
			//R_ASSERT3(og, "collision damage bone has no physics collision", *item.first);
			if(og)og->add_obj_contact_cb(CollisionCallback);
		}
		
	}
}
예제 #4
0
void CBlackGraviArtefact::GraviStrike()
{
	xr_list<s16>		elements_list;
	xr_list<Fvector>	bone_position_list;

	Fvector object_pos					; 
	Fvector strike_dir					;

	rq_storage.r_clear	();

	for(GAME_OBJECT_LIST_it it = m_GameObjectList.begin(); 
						    m_GameObjectList.end() != it;
							++it)
	{
		CPhysicsShellHolder* pGameObject = *it;

		if(pGameObject->Visual()) 
			pGameObject->Center(object_pos); 
		else 
			object_pos.set(pGameObject->Position());

		strike_dir.sub(object_pos, Position()); 
		float distance = strike_dir.magnitude(); 

		float impulse = 100.f*m_fStrikeImpulse * (1.f - (distance/m_fRadius)*
										   (distance/m_fRadius));
						
		if(impulse > .001f) 
		{
//?			BOOL		enabled = getEnabled();
//?			setEnabled	(FALSE);
			impulse		*= CExplosive::ExplosionEffect	(rq_storage,NULL,pGameObject, Position(),m_fRadius);
//?			setEnabled	(enabled);
		}

		float hit_power		;
		CEntityAlive* pEntityAlive = smart_cast<CEntityAlive*>(pGameObject);
		if(pGameObject->m_pPhysicsShell)	hit_power = 0;
		else if(pEntityAlive && pEntityAlive->g_Alive() && 
				pEntityAlive->character_physics_support()->movement()->CharacterExist())
			hit_power = 0;
		else
			hit_power = impulse;

		
		if(impulse > .001f) 
		{
			while(!elements_list.empty()) 
			{
				s16 element = elements_list.front();
				Fvector bone_pos = bone_position_list.front();
				
				NET_Packet		P;
				SHit	HS;
				HS.GenHeader(GE_HIT, pGameObject->ID());	//				u_EventGen		(P,GE_HIT, pGameObject->ID());				
				HS.whoID  =ID();							//				P.w_u16			(ID());
				HS.weaponID = ID();							//				P.w_u16			(ID());
				HS.dir = strike_dir;						//				P.w_dir			(strike_dir);
				HS.power = hit_power;						//				P.w_float		(hit_power);
				HS.boneID = element;						//				P.w_s16			(element);
				HS.p_in_bone_space = bone_pos;				//				P.w_vec3		(bone_pos);
				HS.impulse = impulse;						//				P.w_float		(impulse);
				HS.hit_type = (ALife::eHitTypeWound);		//				P.w_u16			(u16(ALife::eHitTypeWound));
				HS.Write_Packet(P);

				u_EventSend		(P);
				elements_list.pop_front();
				bone_position_list.pop_front();
			}
		}
	}
}
예제 #5
0
파일: PHSkeleton.cpp 프로젝트: 2asoft/xray
bool CPHSkeleton::Spawn(CSE_Abstract *D)
{
	
	CSE_PHSkeleton *po		= smart_cast<CSE_PHSkeleton*>(D);
	VERIFY					(po);

	m_flags					= po->_flags;
	CSE_Visual				*visual = smart_cast<CSE_Visual*>(D);
	VERIFY					(visual);
	m_startup_anim			= visual->startup_animation;

	if(po->_flags.test(CSE_PHSkeleton::flSpawnCopy))
	{
		CPHSkeleton* source=smart_cast<CPHSkeleton*>(Level().Objects.net_Find(po->source_id));
		R_ASSERT2(source,"no source");
		source->UnsplitSingle(this);
		m_flags.set				(CSE_PHSkeleton::flSpawnCopy,FALSE);
		po->_flags.set				(CSE_PHSkeleton::flSpawnCopy,FALSE);
		po->source_id				=BI_NONE;
		return true;
	}
	else 
	{
		CPhysicsShellHolder	*obj	=	PPhysicsShellHolder();
		IKinematics			*K		=	NULL;
		if (obj->Visual())
		{
			K= smart_cast<IKinematics*>(obj->Visual());
			if(K)
			{
				K->LL_SetBoneRoot(po->saved_bones.root_bone);
				K->LL_SetBonesVisible(po->saved_bones.bones_mask);
			}
		}
		SpawnInitPhysics(D);
		RestoreNetState(po);
		if(obj->PPhysicsShell()&&obj->PPhysicsShell()->isFullActive())
			obj->PPhysicsShell()->GetGlobalTransformDynamic(&obj->XFORM());
		
		CPHDestroyableNotificate::spawn_notificate(D);

		if(K)
		{
			CInifile* ini=K->LL_UserData();
			if(ini&&ini->section_exist("collide"))
			{
				if(ini->line_exist("collide","not_collide_parts"))
				{
					CGID gr= CPHCollideValidator::RegisterGroup();
					obj->PPhysicsShell()->RegisterToCLGroup(gr);
				}
			}
			if(ini&&ini->section_exist("collide_parts"))
			{
				if(ini->line_exist("collide_parts","small_object"))
				{
					obj->PPhysicsShell()->SetSmall();
				}
				if(ini->line_exist("collide_parts","ignore_small_objects"))
				{
					obj->PPhysicsShell()->SetIgnoreSmall();
				}
			}
		}
	}
	return false;
}