コード例 #1
0
void CPHCollisionDamageReceiver::CollisionCallback(bool& do_colide,bool bo1,dContact& c,SGameMtl* material_1,SGameMtl* material_2)
{
	if(material_1->Flags.test(SGameMtl::flPassable)||material_2->Flags.test(SGameMtl::flPassable))return;
	dBodyID						b1					=	dGeomGetBody(c.geom.g1)	;
	dBodyID						b2					=	dGeomGetBody(c.geom.g2) ;
	dxGeomUserData				*ud_self			=	bo1 ? retrieveGeomUserData(c.geom.g1):retrieveGeomUserData(c.geom.g2);
	dxGeomUserData				*ud_damager			=	bo1 ? retrieveGeomUserData(c.geom.g2):retrieveGeomUserData(c.geom.g1);
	
	SGameMtl					*material_self		=	bo1 ? material_1:material_2;
	SGameMtl					*material_damager	=	bo1 ? material_2:material_1;
	VERIFY						(ud_self);
	CPhysicsShellHolder			*o_self			=	ud_self->ph_ref_object;
	CPhysicsShellHolder			*o_damager		=	NULL;if(ud_damager)o_damager=ud_damager->ph_ref_object;
	u16							source_id		=	o_damager ? o_damager->ID():u16(-1);
	CPHCollisionDamageReceiver	*dr	=o_self->PHCollisionDamageReceiver();
	VERIFY2(dr,"wrong callback");
	
	float damager_material_factor=material_damager->fBounceDamageFactor;

	if(ud_damager&&ud_damager->ph_object&&ud_damager->ph_object->CastType()==CPHObject::tpCharacter)
	{
		CCharacterPhysicsSupport* phs=o_damager->character_physics_support();
		if(phs->IsSpecificDamager())damager_material_factor=phs->BonceDamageFactor();
	}

	float dfs=(material_self->fBounceDamageFactor+damager_material_factor);
	if(fis_zero(dfs)) return;
	Fvector dir;dir.set(*(Fvector*)c.geom.normal);
	Fvector pos;
	pos.sub(*(Fvector*)c.geom.pos,*(Fvector*)dGeomGetPosition(bo1 ? c.geom.g1:c.geom.g2));//it is not true pos in bone space
	dr->Hit(source_id,ud_self->bone_id,E_NL(b1,b2,c.geom.normal)*damager_material_factor/dfs,dir,pos);
	
}
コード例 #2
0
ファイル: ClimableObject.cpp プロジェクト: 2asoft/xray
void CClimableObject::ObjectContactCallback(bool&	do_colide,bool bo1,dContact& c,SGameMtl * /*material_1*/,SGameMtl * /*material_2*/)
{
	dxGeomUserData* usr_data_1= retrieveGeomUserData(c.geom.g1);
	dxGeomUserData* usr_data_2=retrieveGeomUserData(c.geom.g2);
	dxGeomUserData* usr_data_ch=NULL;
	dxGeomUserData* usr_data_lad=NULL;
	CClimableObject* this_object=NULL;
	CPHCharacter* ch=NULL;
	float norm_sign=0.f;
	if(bo1) {
			usr_data_ch=usr_data_2;
			usr_data_lad=usr_data_1;
			norm_sign=-1.f;
		}
	else {
			norm_sign=1.f;
			usr_data_ch=usr_data_1;
			usr_data_lad=usr_data_2;
	}

	if(usr_data_ch&&usr_data_ch->ph_object&&usr_data_ch->ph_object->CastType()==CPHObject::tpCharacter)
		ch=static_cast<CPHCharacter*>(usr_data_ch->ph_object);
	else
	{
		do_colide=false;
		return;
	}
	VERIFY(ch);
	VERIFY(usr_data_lad);
	this_object=static_cast<CClimableObject*>(usr_data_lad->ph_ref_object);
	VERIFY(this_object);
	if(!this_object->BeforeLadder(ch,-0.1f)) do_colide=false;
	
}
コード例 #3
0
ファイル: CarWheels.cpp プロジェクト: OLR-xray/OLR-3.0
void  CCar::SWheel::WheellCollisionCallback(bool& do_colide,bool bo1,dContact& c,SGameMtl* material_1,SGameMtl* material_2)
{
	
	dxGeomUserData					*ud1			=			retrieveGeomUserData(c.geom.g1)	;
	dxGeomUserData					*ud2			=			retrieveGeomUserData(c.geom.g2)	;
	applywheelCollisionParams		(ud1,do_colide,c,material_1,material_2)						;
	applywheelCollisionParams		(ud2,do_colide,c,material_1,material_2)						;
}
コード例 #4
0
ファイル: PHCapture.cpp プロジェクト: Zen13L/xray-16
void CPHCapture::object_contactCallbackFun(bool& do_colide,bool bo1,dContact& c,SGameMtl * /*material_1*/,SGameMtl * /*material_2*/)
{

    dxGeomUserData *l_pUD1 = NULL;
    dxGeomUserData *l_pUD2 = NULL;
    l_pUD1 = retrieveGeomUserData(c.geom.g1);
    l_pUD2 = retrieveGeomUserData(c.geom.g2);

    if(! l_pUD1) return;
    if(!l_pUD2) return;

    //CEntityAlive* capturer=smart_cast<CEntityAlive*>(l_pUD1->ph_ref_object);
    IPhysicsShellHolder* capturer=(l_pUD1->ph_ref_object);
    if(capturer)
    {
        IPHCapture* icapture=capturer->PHCapture();
        CPHCapture* capture = static_cast<CPHCapture*>(icapture);
        if(capture)
        {
            if(capture->m_taget_element->PhysicsRefObject()==l_pUD2->ph_ref_object)
            {
                do_colide = false;
                capture->m_taget_element->Enable();
                if(capture->e_state==CPHCapture::cstReleased)
                    capture->ReleaseInCallBack();
            }

        }


    }

    capturer=l_pUD2->ph_ref_object;
    if(capturer)
    {
        CPHCapture* capture=static_cast<CPHCapture*>(capturer->PHCapture());
        if(capture)
        {
            if(capture->m_taget_element->PhysicsRefObject()==l_pUD1->ph_ref_object)
            {
                do_colide = false;
                capture->m_taget_element->Enable();
                if(capture->e_state==CPHCapture::cstReleased)
                    capture->ReleaseInCallBack();
            }

        }

    }
}
コード例 #5
0
void  OnCharacterContactInDeath(bool& do_colide,bool bo1,dContact& c,SGameMtl * /*material_1*/,SGameMtl * /*material_2*/)
{
	dSurfaceParameters		&surface=c.surface;
	CCharacterPhysicsSupport* l_character_physic_support=0;
	if (bo1)
	{
		l_character_physic_support=(CCharacterPhysicsSupport*)retrieveGeomUserData(c.geom.g1)->callback_data;
	}
	else
	{
		l_character_physic_support=(CCharacterPhysicsSupport*)retrieveGeomUserData(c.geom.g2)->callback_data;
	}

	surface.mu=l_character_physic_support->m_curr_skin_friction_in_death;
}
コード例 #6
0
void	StaticEnvironment ( bool& do_colide, bool bo1, dContact& c, SGameMtl* material_1, SGameMtl* material_2 )
{
	dJointID contact_joint	= dJointCreateContact(0, ContactGroup, &c);

	if(bo1)
	{
		((CPHActivationShape*)(retrieveGeomUserData(c.geom.g1)->callback_data))->DActiveIsland()->ConnectJoint(contact_joint);
		dJointAttach			(contact_joint, dGeomGetBody(c.geom.g1), 0);
	}
	else
	{
		((CPHActivationShape*)(retrieveGeomUserData(c.geom.g2)->callback_data))->DActiveIsland()->ConnectJoint(contact_joint);
		dJointAttach			(contact_joint, 0, dGeomGetBody(c.geom.g2));
	}
	do_colide=false;
}
コード例 #7
0
IPhysicsShellHolder* CPHActivationShape::ref_object	()
{
	VERIFY(m_geom);
	dxGeomUserData* ud = retrieveGeomUserData( m_geom );
	VERIFY( ud );
	return ud->ph_ref_object;

}
コード例 #8
0
void TTestDepthCallback (bool& do_colide,bool bo1,dContact& c,SGameMtl* material_1,SGameMtl* material_2)
{
	if(saved_callback)saved_callback(do_colide,bo1,c,material_1,material_2);

	if(do_colide&&!material_1->Flags.test(SGameMtl::flPassable) &&!material_2->Flags.test(SGameMtl::flPassable))
	{
		float& depth=c.geom.depth;
		float test_depth=depth-Pars::decrement_depth;
		save_max(max_depth,test_depth);
		c.surface.mu*=Pars::calback_friction_factor;
		if(test_depth>Pars::depth_to_use_force)
		{
			float force = Pars::callback_force_factor*ph_world->Gravity();
			dBodyID b1=dGeomGetBody(c.geom.g1);
			dBodyID b2=dGeomGetBody(c.geom.g2);
			if(b1)dBodyAddForce(b1,c.geom.normal[0]*force,c.geom.normal[1]*force,c.geom.normal[2]*force);
			if(b2)dBodyAddForce(b2,-c.geom.normal[0]*force,-c.geom.normal[1]*force,-c.geom.normal[2]*force);
			dxGeomUserData* ud1=retrieveGeomUserData(c.geom.g1);
			dxGeomUserData* ud2=retrieveGeomUserData(c.geom.g2);

			if(ud1)
			{
				CPhysicsShell* phsl=ud1->ph_ref_object->PPhysicsShell();
				if(phsl) phsl->Enable();
			}

			if(ud2)
			{
				CPhysicsShell* phsl=ud2->ph_ref_object->PPhysicsShell();
				if(phsl) phsl->Enable();
			}


			do_colide=false;
		}
		else if(test_depth>Pars::depth_to_change_softness_pars)
		{
			c.surface.soft_cfm=Pars::callback_cfm_factor;
			c.surface.soft_erp=Pars::callback_erp_factor;
		}
		limit_above(depth,Pars::max_real_depth);
	}

}
コード例 #9
0
ファイル: Helicopter2.cpp プロジェクト: OLR-xray/XRay-NEW
void CollisionCallbackDead(bool& do_colide,bool bo1,dContact& c,SGameMtl* material_1,SGameMtl* material_2)
{	
	do_colide=true; 

	CHelicopter *l_this		= bo1 ? smart_cast<CHelicopter*>(retrieveGeomUserData(c.geom.g1)->ph_ref_object) : smart_cast<CHelicopter*>(retrieveGeomUserData(c.geom.g2)->ph_ref_object);

	if(l_this&& !l_this->m_exploded)
		l_this->m_ready_explode=true;

}
コード例 #10
0
ファイル: BastArtifact.cpp プロジェクト: OLR-xray/OLR-3.0
//вызывается при столкновении мочалки с чем-то
void CBastArtefact::ObjectContactCallback(bool& /**do_colide/**/,bool bo1,dContact& c,SGameMtl * /*material_1*/,SGameMtl * /*material_2*/) 
{
	dxGeomUserData *l_pUD1 = NULL;
	dxGeomUserData *l_pUD2 = NULL;
	l_pUD1 = retrieveGeomUserData(c.geom.g1);
	l_pUD2 = retrieveGeomUserData(c.geom.g2);

	if(!l_pUD1 || !l_pUD2) return;

	//определить кто есть кто, из двух столкнувшихся предметов
	CBastArtefact *pBastArtefact = l_pUD1 ? smart_cast<CBastArtefact*>(l_pUD1->ph_ref_object) : NULL;
	if(!pBastArtefact) pBastArtefact = l_pUD2 ? smart_cast<CBastArtefact*>(l_pUD2->ph_ref_object) : NULL;
	if(!pBastArtefact) return;
	if(!pBastArtefact->IsAttacking()) return;

	CEntityAlive *pEntityAlive = NULL;
	pEntityAlive = l_pUD1 ? smart_cast<CEntityAlive*>(l_pUD1->ph_ref_object) : NULL;
	if(!pEntityAlive) pEntityAlive = l_pUD2 ? smart_cast<CEntityAlive*>(l_pUD2->ph_ref_object) : NULL;

	pBastArtefact->BastCollision(pEntityAlive);
}
コード例 #11
0
ファイル: Physics.cpp プロジェクト: 2asoft/xray
IC static int CollideIntoGroup(dGeomID o1, dGeomID o2,dJointGroupID jointGroup,CPHIsland* world,const int &MAX_CONTACTS)
{
	const int RS= 800+10;
	const int N = RS;
	
	static dContact contacts[RS];
	int	collided_contacts=0;
	// get the contacts up to a maximum of N contacts
	int n;
	
	VERIFY	(o1);
	VERIFY	(o2); 
	VERIFY(&contacts[0].geom);
	n		= dCollide(o1, o2, N, &contacts[0].geom, sizeof(dContact));	

	if(n>N-1)
		n=N-1;
	int i;
	

	for(i = 0; i < n; ++i)
	{
		dContact				&c		=contacts[i];
		dContactGeom			&cgeom	=c.geom;
		dSurfaceParameters		&surface=c.surface;
		dGeomID					g1		=cgeom.g1;
		dGeomID					g2		=cgeom.g2;
		bool pushing_neg=	false;
		bool do_collide	=	true;
		dxGeomUserData* usr_data_1		=NULL;
		dxGeomUserData* usr_data_2		=NULL;
		u16				material_idx_1	=0;
		u16				material_idx_2	=0;

		surface.mu =1.f;// 5000.f;
		surface.soft_erp=1.f;//ERP(world_spring,world_damping);
		surface.soft_cfm=1.f;//CFM(world_spring,world_damping);
		surface.bounce = 0.01f;//0.1f;
		surface.bounce_vel =1.5f;//0.005f;
		usr_data_1 = retrieveGeomUserData(g1);
		usr_data_2 = retrieveGeomUserData(g2);
		///////////////////////////////////////////////////////////////////////////////////////////////////
		if(usr_data_2)	material_idx_2=usr_data_2->material;
		if(usr_data_1)	material_idx_1=usr_data_1->material;
		bool is_tri_1=dTriListClass == dGeomGetClass(g1);
		bool is_tri_2=dTriListClass == dGeomGetClass(g2);
		if(!is_tri_2&&!is_tri_1) surface.mode=0;
		if(is_tri_1) material_idx_1=(u16)surface.mode;
		if(is_tri_2) material_idx_2=(u16)surface.mode;
		SGameMtl* material_1=GMLib.GetMaterialByIdx(material_idx_1);
		SGameMtl* material_2=GMLib.GetMaterialByIdx(material_idx_2);
		////////////////params can be changed in callbacks//////////////////////////////////////////////////////////////////////////
		surface.mode =dContactApprox1|dContactSoftERP|dContactSoftCFM;
		float spring	=material_2->fPHSpring*material_1->fPHSpring*world_spring;
		float damping	=material_2->fPHDamping*material_1->fPHDamping*world_damping;
		surface.soft_erp=ERP(spring,damping);
		surface.soft_cfm=CFM(spring,damping);
		surface.mu=material_2->fPHFriction*material_1->fPHFriction;
		/////////////////////////////////////////////////////////////////////////////////////////////////


		Flags32	&flags_1=material_1->Flags;
		Flags32	&flags_2=material_2->Flags;

		if(is_tri_1)
		{
#pragma warning(push)
#pragma warning(disable:4245)
			if(material_1->Flags.test(SGameMtl::flSlowDown)&&!(usr_data_2->pushing_neg||usr_data_2->pushing_b_neg))
#pragma warning(pop)
			{
				dBodyID body=dGeomGetBody(g2);
				R_ASSERT2(body,"static - static collision !!!");
				if(material_1->Flags.test(SGameMtl::flLiquid))
				{
					add_contact_body_effector(body,c,material_1);
				}
				else
				{
					if(!usr_data_2 || !usr_data_2->ph_object || !usr_data_2->ph_object->IsRayMotion())
					{
						add_contact_body_effector(body,c,material_1);
					}
				}
				
			}
			if(material_1->Flags.test(SGameMtl::flPassable)) 
				do_collide=false;
		//	if(material_2->Flags.is(SGameMtl::flClimable)) 
		//		do_collide=false;
		}
		if(is_tri_2)
		{
#pragma warning(push)
#pragma warning(disable:4245)
			if(material_2->Flags.test(SGameMtl::flSlowDown)&&!(usr_data_1->pushing_neg||usr_data_1->pushing_b_neg))
#pragma warning(pop)
			{

				dBodyID body=dGeomGetBody(g1);
				R_ASSERT2(body,"static - static collision !!!");
				if(material_2->Flags.test(SGameMtl::flLiquid))
				{
					add_contact_body_effector(body,c,material_2);
				}
				else
				{
					if(!usr_data_1 || !usr_data_1->ph_object || !usr_data_1->ph_object->IsRayMotion())
					{
						add_contact_body_effector(body,c,material_2);
					}
				}

			}
			if(material_2->Flags.test(SGameMtl::flPassable)) 
				do_collide=false;

		}
	
		if(flags_1.test(SGameMtl::flBounceable)&&flags_2.test(SGameMtl::flBounceable))
		{
			surface.mode		|=	dContactBounce;
			surface.bounce_vel	=	_max(material_1->fPHBounceStartVelocity,material_2->fPHBounceStartVelocity);
			surface.bounce		=	_min(material_1->fPHBouncing,material_2->fPHBouncing);
		}
		/////////////////////////////////////////////////////////////////////////////////////////////////
		if(usr_data_2&&usr_data_2->object_callbacks){
			usr_data_2->object_callbacks->Call(do_collide,false,c,material_1,material_2);
		}

		if(usr_data_1&&usr_data_1->object_callbacks){
			usr_data_1->object_callbacks->Call(do_collide,true,c,material_1,material_2);
		}

		if(usr_data_2){
			usr_data_2->pushing_b_neg	=	usr_data_2->pushing_b_neg	&& !GMLib.GetMaterialByIdx(usr_data_2->b_neg_tri->material)->Flags.test(SGameMtl::flPassable);
			usr_data_2->pushing_neg		=	usr_data_2->pushing_neg		&& !GMLib.GetMaterialByIdx(usr_data_2->neg_tri->material)->Flags.test(SGameMtl::flPassable);
			pushing_neg=usr_data_2->pushing_b_neg||usr_data_2->pushing_neg;
			if(usr_data_2->ph_object){
				usr_data_2->ph_object->InitContact(&c,do_collide,material_idx_1,material_idx_2);
			}

		}
		///////////////////////////////////////////////////////////////////////////////////////
		if(usr_data_1){ 
			usr_data_1->pushing_b_neg	=	usr_data_1->pushing_b_neg	&& !GMLib.GetMaterialByIdx(usr_data_1->b_neg_tri->material)->Flags.test(SGameMtl::flPassable);
			usr_data_1->pushing_neg		=	usr_data_1->pushing_neg		&& !GMLib.GetMaterialByIdx(usr_data_1->neg_tri->material)->Flags.test(SGameMtl::flPassable);
			pushing_neg=usr_data_1->pushing_b_neg||usr_data_1->pushing_neg;
			if(usr_data_1->ph_object){
				usr_data_1->ph_object->InitContact(&c,do_collide,material_idx_1,material_idx_2);

			}
		}


		if	(pushing_neg)
			surface.mu=dInfinity;
		if	(do_collide && collided_contacts<MAX_CONTACTS)
		{
			++collided_contacts;
			#ifdef DEBUG
			if( ph_dbg_draw_mask.test(phDbgDrawContacts) )
				DBG_DrawContact(c);
			#endif
			dJointID contact_joint	= dJointCreateContact(0, jointGroup, &c);
			world->ConnectJoint(contact_joint);
			dJointAttach			(contact_joint, dGeomGetBody(g1), dGeomGetBody(g2));
		}
	}
	return collided_contacts;
}