Example #1
0
void CODEGeom::add_obj_contact_cb(ObjectContactCallbackFun* occb)
{
	if(!m_geom_transform) return;
	if(geom())
	{
		VERIFY(dGeomGetUserData(geom()));
		dGeomUserDataAddObjectContactCallback(geom(),occb);
	}
	else
	{
		VERIFY(dGeomGetUserData(m_geom_transform));
		dGeomUserDataAddObjectContactCallback(m_geom_transform,occb);
	}
}
bool	CPHActivationShape::	Activate							(const Fvector need_size,u16 steps,float max_displacement,float max_rotation,bool	un_freeze_later/*	=false*/)										
{

#ifdef	DEBUG 
	if(debug_output().ph_dbg_draw_mask().test(phDbgDrawDeathActivationBox))
	{
		debug_output().DBG_OpenCashedDraw();
		Fmatrix M;
		PHDynamicData::DMXPStoFMX(dBodyGetRotation(m_body),dBodyGetPosition(m_body),M);
		Fvector v;dGeomBoxGetLengths(m_geom,cast_fp(v));v.mul(0.5f);
		debug_output().DBG_DrawOBB(M,v,D3DCOLOR_XRGB(0,255,0));
	}
#endif
	VERIFY(m_geom&&m_body);
	CPHObject::activate();
	ph_world->Freeze();
	UnFreeze();
	max_depth=0.f;

	dGeomUserDataSetObjectContactCallback(m_geom,GetMaxDepthCallback)			;
	//ph_world->Step();
	ph_world->StepTouch();	
	u16		num_it =15;
	float	fnum_it=float(num_it);
	float	fnum_steps=float(steps);
	float	fnum_steps_r=1.f/fnum_steps;
	float	resolve_depth=0.01f;
	float	max_vel=max_depth/fnum_it*fnum_steps_r/fixed_step;
	float	limit_l_vel=_max(_max(need_size.x,need_size.y),need_size.z)/fnum_it*fnum_steps_r/fixed_step;

	if(limit_l_vel>default_l_limit)
		limit_l_vel=default_l_limit;

	if(max_vel>limit_l_vel)
		max_vel=limit_l_vel;

	float	max_a_vel=max_rotation/fnum_it*fnum_steps_r/fixed_step;

	if(max_a_vel>default_w_limit)
					max_a_vel=default_w_limit;

	//ph_world->CutVelocity(0.f,0.f);
	dGeomUserDataSetCallbackData(m_geom,this);
	dGeomUserDataSetObjectContactCallback( m_geom, ActivateTestDepthCallback );
	if( m_flags.test( flStaticEnvironment ) )
		dGeomUserDataAddObjectContactCallback(m_geom,StaticEnvironment);
	max_depth=0.f;
	
	Fvector from_size;
	Fvector step_size,size;
	dGeomBoxGetLengths(m_geom,cast_fp(from_size));
	step_size.sub(need_size,from_size);
	step_size.mul(fnum_steps_r);
	size.set(from_size);
	bool ret=false;
	V_PH_WORLD_STATE temp_state;
	ph_world->GetState(temp_state);
	for(int m=0;steps>m;++m)
	{
		//float param =fnum_steps_r*(1+m);
		//InterpolateBox(id,param);
		size.add(step_size);
		dGeomBoxSetLengths(m_geom,size.x,size.y,size.z);
		u16		attempts=10;
		do{
		
			ret=false;
			for(int i=0;num_it>i;++i)
			{
				max_depth=0.f;
				ph_world->Step();
				CHECK_POS(Position(),"pos after ph_world->Step()",false);
				ph_world->CutVelocity(max_vel,max_a_vel);
				CHECK_POS(Position(),"pos after CutVelocity",true);
				//if(m==0&&i==0)ph_world->GetState(temp_state);
				if(max_depth	<	resolve_depth) 
				{
						ret=true;
						break;
				}
			}
			attempts--;
		}while(!ret&&attempts>0);
#ifdef	DEBUG
//		Msg("correction attempts %d",10-attempts);
#endif
	
	}
	RestoreVelocityState(temp_state);
	CHECK_POS(Position(),"pos after RestoreVelocityState(temp_state);",true);
	if(!un_freeze_later)ph_world->UnFreeze();
#ifdef	DEBUG 
	if(debug_output().ph_dbg_draw_mask().test(phDbgDrawDeathActivationBox))
	{
		debug_output().DBG_OpenCashedDraw();
		Fmatrix M;
		PHDynamicData::DMXPStoFMX(dBodyGetRotation(m_body),dBodyGetPosition(m_body),M);
		Fvector v;v.set(need_size);v.mul(0.5f);
		debug_output().DBG_DrawOBB(M,v,D3DCOLOR_XRGB(0,255,255));
		debug_output().DBG_ClosedCashedDraw(30000);
	}
#endif
	return ret;
}