Пример #1
0
void CPHWorld::SetStep(dReal s)
{
	fixed_step											=	s;
	world_cfm											=	CFM(SPRING_S(base_cfm,base_erp,base_fixed_step),DAMPING(base_cfm,base_erp));
	world_erp											=	ERP(SPRING_S(base_cfm,base_erp,base_fixed_step),DAMPING(base_cfm,base_erp));
	world_spring										=	1.0f*SPRING	(world_cfm,world_erp);
	world_damping										=	1.0f*DAMPING(world_cfm,world_erp);
	if(ph_world&&ph_world->Exist())
	{
		float	frame_time					=	Device.fTimeDelta;
		u32		it_number					=	iFloor	(frame_time /fixed_step);
		frame_time							-=	it_number*fixed_step;
		ph_world->m_previous_frame_time		=	frame_time;
		ph_world->m_frame_time				=	frame_time;
	}
}
Пример #2
0
void CPHWorld::Create()
{
	dWorldID phWorld=0;
	if (psDeviceFlags.test(mtPhysics))	Device.seqFrameMT.Add	(this,REG_PRIORITY_HIGH);
	else								Device.seqFrame.Add		(this,REG_PRIORITY_LOW);
	m_commander							=xr_new<CPHCommander>();
	//dVector3 extensions={2048,256,2048};
	/*
	Fbox	level_box		=	Level().ObjectSpace.GetBoundingVolume();
	Fvector level_size,level_center;
	level_box				.	getsize		(level_size);
	level_box				.	getcenter	(level_center);
	dVector3 extensions		=	{ level_size.x ,256.f,level_size.z};
	dVector3 center			=	{level_center.x,0.f,level_center.z};
	*/

#ifdef ODE_SLOW_SOLVER
#else

	dWorldSetAutoEnableDepthSF1(phWorld, 100000000);
	///dWorldSetContactSurfaceLayer(phWorld,0.f);
	//phWorld->contactp.min_depth =0.f;

#endif
	ContactGroup			= dJointGroupCreate(0);		
	dWorldSetGravity		(phWorld, 0,-Gravity(), 0);//-2.f*9.81f
	Mesh.Create				(0,phWorld);
#ifdef PH_PLAIN
	plane=dCreatePlane(Space,0,1,0,0.3f);
#endif

	//const  dReal k_p=2400000.f;//550000.f;///1000000.f;
	//const dReal k_d=200000.f;
	dWorldSetERP(phWorld, ERP(world_spring,world_damping) );
	dWorldSetCFM(phWorld, CFM(world_spring,world_damping));
	//dWorldSetERP(phWorld,  0.2f);
	//dWorldSetCFM(phWorld,  0.000001f);
	disable_count=0;
	m_motion_ray=dCreateRayMotions(0);
	phBoundaries.set(Level().ObjectSpace.GetBoundingVolume());
	phBoundaries.y1-=30.f;
	CPHCollideValidator::Init();
	b_exist=true;
}
Пример #3
0
void CPHCapture::PullingUpdate()
{
    if(!m_taget_element->isActive()||inl_ph_world().Device().dwTimeGlobal-m_time_start>m_capture_time)
    {
        Release();
        return;
    }

    Fvector dir;
    Fvector capture_bone_position;
    //CObject* object=smart_cast<CObject*>(m_character->PhysicsRefObject());
    capture_bone_position.set(m_capture_bone->mTransform.c);
    m_character->PhysicsRefObject()->ObjectXFORM().transform_tiny(capture_bone_position);
    m_taget_element->GetGlobalPositionDynamic(&dir);
    dir.sub(capture_bone_position,dir);
    float dist=dir.magnitude();
    if(dist>m_pull_distance)
    {
        Release();
        return;
    }
    dir.mul(1.f/dist);
    if(dist<m_capture_distance)
    {
        m_back_force=0.f;

        m_joint=dJointCreateBall(0,0);
        m_island.AddJoint(m_joint);
        m_ajoint=dJointCreateAMotor(0,0);
        m_island.AddJoint(m_ajoint);
        dJointSetAMotorMode (m_ajoint, dAMotorEuler);
        dJointSetAMotorNumAxes (m_ajoint, 3);

        CreateBody();
        dBodySetPosition(m_body,capture_bone_position.x,capture_bone_position.y,capture_bone_position.z);
        VERIFY( smart_cast<CPHElement*>(m_taget_element) );
        CPHElement	* e = static_cast<CPHElement*>(m_taget_element);
        dJointAttach(m_joint,m_body,e->get_body());
        dJointAttach(m_ajoint,m_body,e->get_body());
        dJointSetFeedback (m_joint, &m_joint_feedback);
        dJointSetFeedback (m_ajoint, &m_joint_feedback);
        dJointSetBallAnchor(m_joint,capture_bone_position.x,capture_bone_position.y,capture_bone_position.z);


        dJointSetAMotorAxis (m_ajoint, 0, 1, dir.x, dir.y, dir.z);

        if(dir.x>EPS)
        {
            if(dir.y>EPS)
            {
                float mag=dir.x*dir.x+dir.y*dir.y;
                dJointSetAMotorAxis (m_ajoint, 2, 2, -dir.y/mag, dir.x/mag, 0.f);
            }
            else if(dir.z>EPS)
            {
                float mag=dir.x*dir.x+dir.z*dir.z;
                dJointSetAMotorAxis (m_ajoint, 2, 2, -dir.z/mag,0.f,dir.x/mag);
            }
            else
            {
                dJointSetAMotorAxis (m_ajoint, 2, 2, 1.f,0.f,0.f);
            }
        }
        else
        {
            if(dir.y>EPS)
            {

                if(dir.z>EPS)
                {
                    float mag=dir.y*dir.y+dir.z*dir.z;
                    dJointSetAMotorAxis (m_ajoint, 2, 2,0.f,-dir.z/mag,dir.y/mag);
                }
                else
                {
                    dJointSetAMotorAxis (m_ajoint, 2, 2, 0.f,1.f,0.f);
                }
            }
            else
            {
                dJointSetAMotorAxis (m_ajoint, 2, 2, 0.f,0.f,1.f);
            }
        }
        //float hi=-M_PI/2.f,lo=-hi;
        //dJointSetAMotorParam(m_ajoint,dParamLoStop ,lo);
        //dJointSetAMotorParam(m_ajoint,dParamHiStop ,hi);
        //dJointSetAMotorParam(m_ajoint,dParamLoStop2 ,lo);
        //dJointSetAMotorParam(m_ajoint,dParamHiStop2 ,hi);
        //dJointSetAMotorParam(m_ajoint,dParamLoStop3 ,lo);
        //dJointSetAMotorParam(m_ajoint,dParamHiStop3 ,hi);


        dJointSetAMotorParam(m_ajoint,dParamFMax ,m_capture_force*0.2f);
        dJointSetAMotorParam(m_ajoint,dParamVel  ,0.f);

        dJointSetAMotorParam(m_ajoint,dParamFMax2 ,m_capture_force*0.2f);
        dJointSetAMotorParam(m_ajoint,dParamVel2  ,0.f);

        dJointSetAMotorParam(m_ajoint,dParamFMax3 ,m_capture_force*0.2f);
        dJointSetAMotorParam(m_ajoint,dParamVel3  ,0.f);


///////////////////////////////////
        float sf=0.1f,df=10.f;

        float erp=ERP(world_spring*sf,world_damping*df);
        float cfm=CFM(world_spring*sf,world_damping*df);
        dJointSetAMotorParam(m_ajoint,dParamStopERP ,erp);
        dJointSetAMotorParam(m_ajoint,dParamStopCFM ,cfm);

        dJointSetAMotorParam(m_ajoint,dParamStopERP2 ,erp);
        dJointSetAMotorParam(m_ajoint,dParamStopCFM2 ,cfm);

        dJointSetAMotorParam(m_ajoint,dParamStopERP3 ,erp);
        dJointSetAMotorParam(m_ajoint,dParamStopCFM3 ,cfm);
        /////////////////////////////////////////////////////////////////////
        ///dJointSetAMotorParam(m_joint1,dParamFudgeFactor ,0.1f);
        //dJointSetAMotorParam(m_joint1,dParamFudgeFactor2 ,0.1f);
        //dJointSetAMotorParam(m_joint1,dParamFudgeFactor3 ,0.1f);
        /////////////////////////////////////////////////////////////////////////////
        sf=0.1f,df=10.f;
        erp=ERP(world_spring*sf,world_damping*df);
        cfm=CFM(world_spring*sf,world_damping*df);
        dJointSetAMotorParam(m_ajoint,dParamCFM ,cfm);
        dJointSetAMotorParam(m_ajoint,dParamCFM2 ,cfm);
        dJointSetAMotorParam(m_ajoint,dParamCFM3 ,cfm);


///////////////////////////

        //dJointSetAMotorParam(m_ajoint,dParamLoStop ,0.f);
        //dJointSetAMotorParam(m_ajoint,dParamHiStop ,0.f);
        m_taget_element->set_LinearVel ( Fvector().set( 0 ,0, 0 ) );
        m_taget_element->set_AngularVel( Fvector().set( 0 ,0, 0 ) );


        m_taget_element->set_DynamicLimits();
        //m_taget_object->PPhysicsShell()->set_JointResistance()
        e_state=cstCaptured;
        return;
    }
    m_taget_element->applyForce(dir,m_pull_force);
}
Пример #4
0
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;
}
Пример #5
0
const dReal 		default_l_limit									= 150.f;//(3.f/fixed_step=0.02f);
const dReal 		default_l_scale									= 1.01f;
const dReal 		default_w_scale									= 1.01f;
const dReal			default_k_l										= 0.0002f;//square resistance !!
const dReal			default_k_w										= 0.05f;

const dReal			mass_limit										= 10000.f;//some conventional value used as evaluative param (there is no code restriction on mass)
extern const u16	max_joint_allowed_for_exeact_integration		= 30;

//base	params
const dReal base_fixed_step											=	0.02f				;
const dReal base_erp												=	0.54545456f			;
const dReal base_cfm												=	1.1363636e-006f		;
//base params
dReal 			fixed_step											=	0.01f;
dReal 			world_cfm											=	CFM(SPRING_S(base_cfm,base_erp,base_fixed_step),DAMPING(base_cfm,base_erp));
dReal 			world_erp											=	ERP(SPRING_S(base_cfm,base_erp,base_fixed_step),DAMPING(base_cfm,base_erp));
dReal			world_spring										=	1.0f*SPRING	(world_cfm,world_erp);
dReal			world_damping										=	1.0f*DAMPING(world_cfm,world_erp);


const dReal			default_world_gravity							=	2*9.81f;


/////////////////////////////////////////////////////

int			phIterations											= 18;
float		phTimefactor											= 1.f;
float		phBreakCommonFactor										= 0.01f;
float		phRigidBreakWeaponFactor								= 1.f;
Fbox		phBoundaries											= {1000.f,1000.f,-1000.f,-1000.f};