Exemple #1
0
//проверка на попадание "осколком" по объекту
ICF static BOOL grenade_hit_callback(collide::rq_result& result, LPVOID params)
{
	SExpQParams& ep	= *(SExpQParams*)params;
	u16 mtl_idx			= GAMEMTL_NONE_IDX;
	if(result.O){
		CKinematics* V  = 0;
		if (0!=(V=smart_cast<CKinematics*>(result.O->Visual()))){
			CBoneData& B= V->LL_GetData((u16)result.element);
			mtl_idx		= B.game_mtl_idx;
		}
	}else{
		//получить треугольник и узнать его материал
		CDB::TRI* T		= Level().ObjectSpace.GetStaticTris()+result.element;
		mtl_idx			= T->material;
	}	
	SGameMtl* mtl		= GMLib.GetMaterialByIdx(mtl_idx);
	ep.shoot_factor		*=mtl->fShootFactor;
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
		Fvector p;p.set(ep.l_dir);p.mul(result.range);p.add(ep.source_p);
		u8 c	=u8(mtl->fShootFactor*255.f);
		DBG_DrawPoint(p,0.1f,D3DCOLOR_XRGB(255-c,0,c));
	}
#endif
	return				(ep.shoot_factor>0.01f);
}
void ik_foot_collider::collide( SIKCollideData &cld, const ik_foot_geom &foot_geom, CGameObject *O, bool foot_step )
{
	VERIFY( foot_geom.is_valid() ); 
	cld.collided = false;
	
	
	float pick_dist = collide_dist;
	//if( foot_step )
	pick_dist += reach_dist ;

//////////////////////////////////////////////////////////////////////////////////////
	const Fvector& toe_pick_v	= cld.m_pick_dir; 
	const Fvector pos_toe		= Fvector().sub( foot_geom.pos_toe(), Fvector( ).mul( toe_pick_v, collide_dist ) );
	ik_pick_query  q_toe( ik_foot_geom::toe, pos_toe, toe_pick_v, pick_dist );

////////////////////////////////////////////////////////////////////////////////////////
	const	Fvector hill_pick_v = cld.m_pick_dir;
	const	Fvector pos_heel	= Fvector().sub( foot_geom.pos_heel(), Fvector( ).mul( hill_pick_v, collide_dist ) );
	ik_pick_query  q_heel( ik_foot_geom::heel, pos_heel, hill_pick_v, pick_dist );

//////////////////////////////////////////////////////////////////////////////////////////
	const	Fvector side_pick_v = cld.m_pick_dir;
	const	Fvector pos_side	= Fvector().sub( foot_geom.pos_side(), Fvector( ).mul( side_pick_v, collide_dist ) );
	ik_pick_query  q_side( ik_foot_geom::side, pos_side, side_pick_v, pick_dist );
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	if( previous_toe_query.is_equal		( q_toe  )	&& 
		previous_heel_query.is_equal( q_heel )	&& 
		previous_side_query.is_equal( q_side ) 
	){
		cld = previous_data;
		return;
	}

	const float foot_length = Fvector().sub( pos_toe, pos_heel ).magnitude() * 1.5f;

	previous_heel_query = q_heel;
	previous_side_query = q_side;
	previous_toe_query	= q_toe;

	ik_pick_result r_toe(ik_foot_geom::toe);
	cld.collided = Pick( r_toe, q_toe, O );
	cld.m_plane = r_toe.p;
	cld.m_collide_point = ik_foot_geom::toe;
//////////////////////////////////////////////////////////////////////////////////////
	

#ifdef DEBUG
	if( ph_dbg_draw_mask1.test( phDbgDrawIKCollision ) )
	{
		DBG_DrawPoint( pos_toe, 0.01, D3DCOLOR_XRGB( 255, 0, 0));
		if(cld.collided)
			DBG_DrawPoint( r_toe.position, 0.01, D3DCOLOR_XRGB( 0, 0, 255));
	}
#endif

	ik_pick_result r_heel(ik_foot_geom::heel); 
	bool heel_collided = Pick( r_heel, q_heel, O ) ;

	ik_pick_result r_side(ik_foot_geom::side); 
	bool side_collided = Pick( r_side, q_side, O ) ;

	bool toe_heel_compatible = cld.collided && heel_collided && Fvector().sub( r_heel.position, r_toe.position ).magnitude() < foot_length;
	bool toe_side_compatible = cld.collided && side_collided && Fvector().sub( r_side.position, r_toe.position ).magnitude() < foot_length;


/*
	if( hill_collided )
	{
		if( !cld.collided || (r_hill.position.y - r_toe.position.y) > EPS )
		{
			cld.m_plane = r_heel.p;
			cld.m_collide_point = ik_foot_geom::heel;
			cld.collided = true;
			cld.m_pick_dir = heel_pick_v;
			
		} 
	}
*/


	if( toe_heel_compatible && toe_side_compatible )
	{
		
			Fplane plane;
			tri_plane( r_toe.position, r_heel.position , r_side.position, plane );
			if( plane.n.dotproduct( r_toe.p.n ) < 0.f )
			{
							
				plane.n.invert();
				plane.d = -plane.d;
			}

			 cld.m_plane  = plane;
#ifdef DEBUG
			if( ph_dbg_draw_mask1.test( phDbgDrawIKCollision ) )
			{
				DBG_DrawPoint( pos_toe, 0.01, D3DCOLOR_XRGB( 255, 0, 0));
				if(cld.collided)
				{
					 DBG_DrawTri( r_toe.position, r_heel.position, r_side.position, D3DCOLOR_XRGB( 0, 0, 255), false );
				}
			}
#endif
			previous_data = cld;
			return;
	}

	float hight = -FLT_MAX;
	ik_pick_result r = r_toe;

	
	if( cld.collided )
	{
		hight = r_toe.position.y;
	}

	if( heel_collided && r_heel.position.y > hight )
	{
		r = r_heel;
		hight = r_heel.position.y;
		cld.collided = true;
	}

	if( side_collided && r_side.position.y > hight )
	{
		r = r_side;
		hight = r_side.position.y;
		cld.collided = true;
	}

	if( cld.collided )
	{
		cld.m_plane = r.p;
		cld.m_collide_point =r.point;
		previous_data = cld;
		return;
	}


	//chose_best_plane( cld.m_plane, pick_v, plane, r_hill.p, r_toe.p   );


	previous_data = cld;

/*
	float u,v,d;
	if( ( !cld.collided ||
		  !( CDB::TestRayTri(pos_hill, pick_v, r_toe.triangle, u, v, d, true ) && d > 0.f ) ) &&
		    Pick( r_hill, pos_hill, pick_v, pick_dist, O ) )
	{

		if( !cld.collided || r_hill.position.y > r_toe.position.y )
		{
			cld.m_plane = r_hill.p;
			cld.m_collide_point = SIKCollideData::heel;
		} 
		
		//else
		//{
		//		ik_pick_result r_foot;
		//		Fvector pos_foot = Fvector().sub( foot.c, Fvector( ).mul( pick_v, collide_dist ) );
		//		if( cld.collided && Pick( r_foot, pos_foot, pick_v, pick_dist, O ) )
		//		{
		//			Fplane plane;
		//			tri_plane( r_toe.position, r_hill.position , r_foot.position, plane );

		//			DBG_DrawTri(r_toe.position, r_hill.position, r_foot.position , D3DCOLOR_XRGB( 255, 255, 255 ), false  );
		//		
		//			if( plane.n.dotproduct( r_hill.p.n ) < 0.f )
		//			{
		//				plane.n.invert();
		//				plane.d = -cld.m_plane.d;
		//			
		//			}
		//			chose_best_plane( cld.m_plane, pick_v, plane, r_hill.p, r_toe.p   );
		//		}
		//}
		
		cld.collided = true;
	}
*/
}
Exemple #3
0
void CExplosive::Explode()
{
	VERIFY(0xffff != Initiator());
	VERIFY(m_explosion_flags.test(flReadyToExplode));//m_bReadyToExplode
	VERIFY(!ph_world->Processing());
	//m_bExploding = true;
	m_explosion_flags.set(flExploding,TRUE);
	cast_game_object()->processing_activate();

	Fvector& pos = m_vExplodePos;
	Fvector& dir = m_vExplodeDir;
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
		DBG_OpenCashedDraw();
		DBG_DrawPoint(pos,0.3f,D3DCOLOR_XRGB(255,0,0));
	}
#endif
//	Msg("---------CExplosive Explode [%d] frame[%d]",cast_game_object()->ID(), Device.dwFrame);
	OnBeforeExplosion();
	//играем звук взрыва
	Sound->play_at_pos(sndExplode, 0, pos, false);
	
	//показываем эффекты

	m_wallmark_manager.PlaceWallmarks		(pos);

	Fvector									vel;
	smart_cast<CPhysicsShellHolder*>(cast_game_object())->PHGetLinearVell(vel);

	Fmatrix explode_matrix;
	explode_matrix.identity();
	explode_matrix.j.set(dir);
	Fvector::generate_orthonormal_basis(explode_matrix.j, explode_matrix.i, explode_matrix.k);
	explode_matrix.c.set(pos);

	CParticlesObject* pStaticPG; 
	pStaticPG = CParticlesObject::Create(*m_sExplodeParticles,!m_bDynamicParticles); 
	if (m_bDynamicParticles) m_pExpParticle = pStaticPG;
	pStaticPG->UpdateParent(explode_matrix,vel);
	pStaticPG->Play();

	//включаем подсветку от взрыва
	StartLight();

	//trace frags
	Fvector frag_dir; 
	
	//////////////////////////////
	//осколки
	//////////////////////////////
	//-------------------------------------
	bool SendHits = false;
	if (OnServer()) SendHits = true;
	else SendHits = false;


	for(int i = 0; i < m_iFragsNum; ++i){
		frag_dir.random_dir	();
		frag_dir.normalize	();
		
		CCartridge cartridge;
		cartridge.m_kDist					= 1.f;
		cartridge.m_kHit					= 1.f;
		cartridge.m_kImpulse				= 1.f;
		cartridge.m_kPierce					= 1.f;
		cartridge.fWallmarkSize				= fWallmarkSize;
		cartridge.bullet_material_idx		= GMLib.GetMaterialIdx(WEAPON_MATERIAL_NAME);
		cartridge.m_flags.set				(CCartridge::cfTracer,FALSE);

		Level().BulletManager().AddBullet(	pos, frag_dir, m_fFragmentSpeed,
											m_fFragHit, m_fFragHitImpulse, Initiator(),
											cast_game_object()->ID(), m_eHitTypeFrag, m_fFragsRadius, 
											cartridge, SendHits );
	}	

	if (cast_game_object()->Remote()) return;
	
	/////////////////////////////////
	//взрывная волна
	////////////////////////////////
	//---------------------------------------------------------------------
	xr_vector<ISpatial*>	ISpatialResult;
	g_SpatialSpace->q_sphere(ISpatialResult,0,STYPE_COLLIDEABLE,pos,m_fBlastRadius);

	m_blasted_objects.clear	();
	for (u32 o_it=0; o_it<ISpatialResult.size(); o_it++)
	{
		ISpatial*		spatial	= ISpatialResult[o_it];
		//		feel_touch_new(spatial->dcast_CObject());

		CPhysicsShellHolder	*pGameObject = smart_cast<CPhysicsShellHolder*>(spatial->dcast_CObject());
		if(pGameObject && cast_game_object()->ID() != pGameObject->ID()) 
			m_blasted_objects.push_back(pGameObject);
	}

	GetExplosionBox(m_vExplodeSize);
START_PROFILE("explosive/activate explosion box")
	ActivateExplosionBox(m_vExplodeSize,m_vExplodePos);
STOP_PROFILE
	//---------------------------------------------------------------------
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
		DBG_ClosedCashedDraw(100000);
		
	}
#endif
	//////////////////////////////////////////////////////////////////////////
	// Explode Effector	//////////////
	CGameObject* GO = smart_cast<CGameObject*>(Level().CurrentEntity());
	CActor* pActor = smart_cast<CActor*>(GO);
	if(pActor)
	{
		float dist_to_actor = pActor->Position().distance_to(pos);
		float max_dist		= EFFECTOR_RADIUS;
		if (dist_to_actor < max_dist)
			AddEffector	(pActor, effExplodeHit, effector.effect_sect_name, (max_dist - dist_to_actor) / max_dist );
	}
}
Exemple #4
0
float CExplosive::ExplosionEffect(collide::rq_results& storage, CExplosive*exp_obj,CPhysicsShellHolder*blasted_obj,  const Fvector &expl_centre, const float expl_radius) 
{
	
	const Fmatrix	&obj_xform=blasted_obj->XFORM();
	Fmatrix	inv_obj_form;inv_obj_form.invert(obj_xform);
	Fvector	local_exp_center;inv_obj_form.transform_tiny(local_exp_center,expl_centre);

	const Fbox &l_b1 = blasted_obj->BoundingBox();
	if(l_b1.contains(local_exp_center)) 
										return 1.f;
	Fvector l_c, l_d;l_b1.get_CD(l_c,l_d);
	float effective_volume=l_d.x*l_d.y*l_d.z;
	float max_s=effective_volume/(_min(_min(l_d.x,l_d.y),l_d.z));
	if(blasted_obj->PPhysicsShell()&&blasted_obj->PPhysicsShell()->isActive())
	{
		float ph_volume=blasted_obj->PPhysicsShell()->getVolume();
		if(ph_volume<effective_volume)effective_volume=ph_volume;
	}
	float effect=0.f;
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
		Fmatrix dbg_box_m;dbg_box_m.set(obj_xform);
		dbg_box_m.c.set(l_c);obj_xform.transform(dbg_box_m.c);
		DBG_DrawOBB(dbg_box_m,l_d,D3DCOLOR_XRGB(255,255,0));
	}
#endif

	for(u16 i=0;i<TEST_RAYS_PER_OBJECT;++i){
		Fvector l_source_p,l_end_p;
		l_end_p.random_point(l_d);
		l_end_p.add(l_c);
		obj_xform.transform_tiny(l_end_p);
		GetRaySourcePos(exp_obj,expl_centre,l_source_p);
		Fvector l_local_source_p;inv_obj_form.transform_tiny(l_local_source_p,l_source_p);
		if(l_b1.contains(l_local_source_p))
		{
			effect+=1.f;continue;
		}
		Fvector l_dir; l_dir.sub(l_end_p,l_source_p);
		float mag=l_dir.magnitude();
		
		if(fis_zero(mag)) return 1.f;

		l_dir.mul(1.f/mag);
#ifdef DEBUG
			if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
			{
			DBG_DrawPoint(l_source_p,0.1f,D3DCOLOR_XRGB(0,0,255));
			DBG_DrawPoint(l_end_p,0.1f,D3DCOLOR_XRGB(0,0,255));
			DBG_DrawLine(l_source_p,l_end_p,D3DCOLOR_XRGB(0,0,255));
			}
#endif
		
#ifdef DEBUG
		float l_S=effective_volume*(_abs(l_dir.dotproduct(obj_xform.i))/l_d.x+_abs(l_dir.dotproduct(obj_xform.j))/l_d.y+_abs(l_dir.dotproduct(obj_xform.k))/l_d.z);
		float add_eff=_sqrt(l_S/max_s)*TestPassEffect(l_source_p,l_dir,mag,expl_radius,storage,blasted_obj);
		effect+=add_eff;
		if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
		{
			Msg("dist %f,effect R %f",mag,expl_radius);
			Msg("test pass effect %f",add_eff);
			Msg("S effect %f",_sqrt(l_S/max_s));
			Msg("dist/overlap effect, %f",add_eff/_sqrt(l_S/max_s));
		}
#else
		float l_S=effective_volume*(_abs(l_dir.dotproduct(obj_xform.i))/l_d.x+_abs(l_dir.dotproduct(obj_xform.j))/l_d.y+_abs(l_dir.dotproduct(obj_xform.k))/l_d.z);
		effect+=_sqrt(l_S/max_s)*TestPassEffect(l_source_p,l_dir,mag,expl_radius,storage,blasted_obj);
#endif

	}
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
			Msg("damage effect %f",effect/TEST_RAYS_PER_OBJECT);
	}
#endif
	return effect/TEST_RAYS_PER_OBJECT;
	
}
Exemple #5
0
bool CIKFoot::GetFootStepMatrix( ik_goal_matrix &m, const Fmatrix &g_anim, const  SIKCollideData &cld, bool collide, bool rotation, bool b_make_shift/*=true*/ )const
{
	const Fmatrix global_anim = g_anim;
	Fvector	local_point;		ToePosition( local_point );													//toe position in bone[2] space
	Fvector	global_point;		global_anim.transform_tiny( global_point, local_point );						//non collided toe in global space
	Fvector foot_normal;		FootNormal( foot_normal );
	global_anim.transform_dir( foot_normal );
#ifdef DEBUG
		//if( ph_dbg_draw_mask.test( phDbgDrawIKGoal ) )
		//{
		//	DBG_DrawLine( global_point, Fvector().add( global_point, foot_normal ), D3DCOLOR_XRGB( 0, 255, 255) );
		//}
#endif
	if( cld.m_collide_point == ik_foot_geom::heel || cld.m_collide_point == ik_foot_geom::side )
	{
		Fmatrix foot;ref_bone_to_foot( foot, g_anim );
		Fvector heel;
		HeelPosition( heel );
		foot.transform_tiny(global_point, heel );
#ifdef DEBUG
		if( ph_dbg_draw_mask.test( phDbgDrawIKGoal ) )
			DBG_DrawPoint( global_point, 0.01, D3DCOLOR_XRGB( 0, 255, 255));
#endif
		Fmatrix foot_to_ref;
		ref_bone_to_foot_transform(foot_to_ref).transform_tiny(local_point, heel );
	}

	float	dtoe_tri		=-cld.m_plane.d - cld.m_plane.n.dotproduct( global_point );	
	if(  !cld.collided ||  _abs( dtoe_tri ) > collide_dist )
	{
		m.set( global_anim, ik_goal_matrix::cl_free );
		return false;
	}

	Fplane p = cld.m_plane;
	Fmatrix xm; xm.set( global_anim );
	ik_goal_matrix::e_collide_state cl_state = ik_goal_matrix::cl_undefined;
	if( rotation )//!collide || ik_allign_free_foot
		cl_state = rotate( xm, p, foot_normal, global_point, collide );

	if( b_make_shift && make_shift( xm, local_point, collide, p, cld.m_pick_dir ) )
		switch( cl_state )
		{
			case ik_goal_matrix::cl_aligned		:					break;
			case ik_goal_matrix::cl_undefined	:
			case ik_goal_matrix::cl_free		:
					cl_state = ik_goal_matrix::cl_translational;	break;
			case ik_goal_matrix::cl_rotational:
					cl_state = ik_goal_matrix::cl_mixed;			break;
			default:		NODEFAULT;
			
		}
	else if( cl_state == ik_goal_matrix::cl_undefined )
			cl_state = ik_goal_matrix::cl_free;
	

	VERIFY( _valid( xm ) );
	m.set( xm, cl_state );
#ifdef DEBUG
	if(ph_dbg_draw_mask.test( phDbgDrawIKGoal ))
	{
		DBG_DrawPoint( global_point, 0.03f, D3DCOLOR_RGBA( 255, 0, 0, 255 ) );
	}
	if(!fsimilar( _abs( DET( g_anim ) - 1.f ), _abs( DET( m.get() ) - 1.f ), 0.001f ) )
		Msg("scale g_anim: %f scale m: %f ",  DET( g_anim ) ,  DET( m.get() ) );
#endif

	return true;
}