⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ivp_mindist_friction.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 2 页
字号:
        last_gap_len = length; 
	info->surf_normal.set_multiple(&world_diff_vec, 1.0f/length);
    }else{
        last_gap_len = 0.0f; 
	info->surf_normal.set_multiple(&norm, 1.0f/ IVP_Inline_Math::ivp_sqrtf(quad_dist));
    }

    info->span_friction_v[0].set(&Kvec);
    info->contact_point_ws.set(&world_edge_space0);

    if (cp_status == IVP_CPBS_NEEDS_RECHECK){
	this->cp_status = IVP_CPBS_NORMAL;
	if (sl < 0.0f || sl > 1.0f || sk < 0.0f || sk > 1.0f) {
	    info->friction_is_broken = IVP_TRUE;
	}
    }

#ifdef IVP_USE_S_VALS_FOR_PRETENSION        
    IVP_DOUBLE old_sk = s_coords[0];
    IVP_DOUBLE old_sl = s_coords[1];
    diff_contact_vec->set_multiple(&vec0,sk - old_sk);
    diff_contact_vec->add_multiple(&vec1,old_sl - sl);    
    s_coords[0] = sk;
    s_coords[1] = sl;
#endif  

  } else {
      info->friction_is_broken = IVP_TRUE;
      diff_contact_vec->set_to_zero();
      last_gap_len = ivp_mindist_settings.keeper_dist;
      info->contact_point_ws.set(&Kp);
      info->surf_normal.set(1.0f,0.0f,0.0f);
      info->span_friction_v[0].set(0.0f,1.0f,0.0f);
      sk=0.0f;
      sl=0.0f;
  }
}

void IVP_Contact_Point::reset_time(IVP_Time offset){
    last_time_of_recalc_friction_s_vals -= offset;
}

void IVP_Contact_Point::recalc_friction_s_vals(){
    IVP_Environment *env = get_synapse(0)->get_object()->get_environment();
    
    IVP_Impact_Solver_Long_Term *info = (IVP_Impact_Solver_Long_Term*)env->get_sim_unit_mem()->get_mem_transaction(sizeof(IVP_Impact_Solver_Long_Term));
    info->init_tmp_contact_info();
    this->tmp_contact_info = info;
    	    
    IVP_Synapse_Friction *syn0 = this->get_synapse(0);
    IVP_Synapse_Friction *syn1 = this->get_synapse(1);
    
    env->get_statistic_manager()->processed_fmindists++;

    IVP_SYNAPSE_POLYGON_STATUS stat0 = syn0->get_status();
    IVP_SYNAPSE_POLYGON_STATUS stat1 = syn1->get_status();
    
    // set: 	this->info.gap_distance, info->surf_normal, info->contact_points_ws[0],
    //		this->span_friction_v[0]
    //          [and add to diff_vec_contact]
    { 
      IVP_U_Float_Point diff_vec_contact; diff_vec_contact.set_to_zero();
	IVP_Cache_Ledge_Point m_cache_0;
	IVP_Cache_Ledge_Point m_cache_1;	

	const IVP_Compact_Edge *e1 = syn1->edge;
	m_cache_1.init_cache_ledge_point(syn1->l_obj,e1->get_compact_ledge());
	m_cache_1.tmp.synapse_friction = syn1;

	const IVP_Compact_Edge *e0 = syn0->edge;
	m_cache_0.init_cache_ledge_point(syn0->l_obj,e0->get_compact_ledge());
	m_cache_0.tmp.synapse_friction = syn0;
    
	IVP_U_Point point0_position_ws; // for ball and point cases

	switch(stat0){
	    
	case IVP_ST_BALL:{
	    point0_position_ws.set(m_cache_0.get_object_cache()->m_world_f_object.get_position());
	    this->cp_status = IVP_CPBS_NEEDS_RECHECK;
	    goto ball_same_as_point;
	}
   
	case IVP_ST_POINT:{
	    IVP_CLS.give_world_coords_AT(e0, &m_cache_0, &point0_position_ws);

	ball_same_as_point:	    
	    switch(stat1){
	    case IVP_ST_BALL:{
		IVP_U_Point *tp2 = m_cache_1.get_object_cache()->m_world_f_object.get_position();
		p_calc_friction_s_PP(&point0_position_ws,tp2,info,&diff_vec_contact);
		break;
	    }
	    
	    case IVP_ST_POINT:{
		IVP_U_Point tp2; IVP_CLS.give_world_coords_AT(e1, &m_cache_1, &tp2);
		p_calc_friction_s_PP(&point0_position_ws,&tp2,info,&diff_vec_contact);
		break;
	    }
	    case IVP_ST_EDGE:{
		p_calc_friction_s_PK(&point0_position_ws, e1, &m_cache_1,info,&diff_vec_contact);
		break;
	    }
	    case IVP_ST_TRIANGLE:{
		p_calc_friction_qr_PF(&point0_position_ws, e1, &m_cache_1,info,&diff_vec_contact);
		break;
	    }
	    default:
		CORE;
	    }
	    break;
	};
	case IVP_ST_EDGE:{
	    IVP_ASSERT( syn1->get_status() == IVP_ST_EDGE );
	    p_calc_friction_ss_KK(e0, e1, &m_cache_0, &m_cache_1,info,&diff_vec_contact);
	    break;
	};
	default:
	    CORE;
	}
	{  // reduce len of friction contact by extra radius
	    IVP_FLOAT first_radius = syn0->l_obj->get_extra_radius();
	    info->contact_point_ws.add_multiple(&info->surf_normal, first_radius);
	    last_gap_len -= first_radius + syn1->l_obj->get_extra_radius();
	}

	//TL: workaround for penetrating balls (shifted mass center)
	if ( last_gap_len < 0.0f ) {
		last_gap_len = 0.0f;
	}    
	m_cache_0.remove_reference();
	m_cache_1.remove_reference();
    }
    info->span_friction_v[0].normize();
    info->span_friction_v[1].inline_calc_cross_product(&info->surf_normal,&info->span_friction_v[0]);
        
// TL:
// IVP_Contact_Point needs for later calculations:
//   both points in world coords
//   both points in object coords
//   normized vector in world coords pointing to first synapse
//   two normized vectors in obj coords pointing to synapse
//   ...
// #+# maybe optimize! e.g.: obj-coords of point synapse never change !

    IVP_U_Float_Point delta_velocity_ws;
    {// calculate some values plus pretension for core 0

	IVP_Core *core0  = syn0->get_object()->get_core();
	
	if (!core0->physical_unmoveable) { // && !core0->pinned){ //@@CBPIN
	    IVP_U_Float_Point surface_normal_cs; // pointing to synapse

	    const IVP_U_Matrix *m_world_f_core = core0->get_m_world_f_core_PSI();
	    m_world_f_core->inline_vimult4(&info->contact_point_ws, &info->contact_point_cs[0]);
	    m_world_f_core->inline_vimult3(&info->surf_normal,&surface_normal_cs);

	    info->contact_cross_nomal_cs[0].inline_calc_cross_product(&info->contact_point_cs[0],& surface_normal_cs );
	    core0->get_surface_speed_on_test(&info->contact_point_cs[0],&core0->speed,&core0->rot_speed,&delta_velocity_ws);

	    IVP_U_Float_Point hp; hp.set_pairwise_mult( &info->contact_cross_nomal_cs[0], core0->get_inv_rot_inertia());
	    info->inv_virtual_mass = info->contact_cross_nomal_cs[0].dot_product( &hp) + core0->get_inv_mass();
	}else{
	    core0 = NULL;
	    delta_velocity_ws.set_to_zero();
	    info->inv_virtual_mass = 0.0f;
	    info->contact_point_cs[0].set_to_zero();
	    info->contact_cross_nomal_cs[0].set_to_zero();
	}
	info->contact_core[0] = core0;
    }
    { // core 1
	IVP_Core *core1  = syn1->get_object()->get_core();
	if (!core1->physical_unmoveable) {// && !core1->pinned){ //@@CBPIN
	    IVP_U_Float_Point surface_normal_cs; // pointing to synapse

	    const IVP_U_Matrix *m_world_f_core = core1->get_m_world_f_core_PSI();
	    m_world_f_core->inline_vimult4(&info->contact_point_ws, &info->contact_point_cs[1]);
	    m_world_f_core->inline_vimult3(&info->surf_normal, &surface_normal_cs);

	    info->contact_cross_nomal_cs[1].inline_calc_cross_product(&info->contact_point_cs[1],&surface_normal_cs );

	    IVP_U_Float_Point dh;
	    core1->get_surface_speed_on_test(&info->contact_point_cs[1],&core1->speed,&core1->rot_speed,&dh);
	    delta_velocity_ws.subtract(&dh);

	    IVP_U_Float_Point hp; hp.set_pairwise_mult( &info->contact_cross_nomal_cs[1], core1->get_inv_rot_inertia());
	    info->inv_virtual_mass += info->contact_cross_nomal_cs[1].dot_product( & hp) + core1->get_inv_mass();
	}else{
	    info->contact_point_cs[1].set_to_zero();
	    info->contact_cross_nomal_cs[1].set_to_zero();
	    core1 = NULL;
	}
	info->contact_core[1] = core1;
    }
    info->virtual_mass = 1.0f/ info->inv_virtual_mass;
    {
	IVP_Time ctime = syn0->get_object()->environment->get_current_time();
	IVP_DOUBLE dt = ctime - this->last_time_of_recalc_friction_s_vals;
	this->last_time_of_recalc_friction_s_vals = ctime;

	//vector of v[0]*s[0] + v[1]*s[1] is real world force vector of force that has to be done on first obj (is pointing to second obj)
	this->span_friction_s[0] -= delta_velocity_ws.dot_product(&info->span_friction_v[0]) * dt;
	this->span_friction_s[1] -= delta_velocity_ws.dot_product(&info->span_friction_v[1]) * dt;
    this->last_contact_point_ws.set( &info->contact_point_ws );
	}
}


IVP_Contact_Point *IVP_Friction_Manager::get_associated_contact_point(IVP_Mindist *mindist) {
    // does a contact_point with same objs and position_status already exist? 
    {
	IVP_Synapse_Friction *syn0;
	IVP_Real_Object *obj0 = mindist->get_synapse(0)->get_object();
	IVP_Real_Object *obj1 = mindist->get_synapse(1)->get_object();
	// search all friction mindist, which are connected to obj0
	// start deep search only if obj1 is connected to mindist also
	for (syn0 = obj0->get_first_friction_synapse(); syn0; syn0 = syn0->get_next()){
	    IVP_Contact_Point *md = syn0->get_contact_point();
	    if ( md->get_synapse(0)->get_object() == obj1 ||  md->get_synapse(1)->get_object() == obj1 ){
		if ( md->is_same_as(mindist)){
		    return md;		    
		}
	    }
	}
    }
    return NULL;
}

void IVP_Friction_Manager::delete_all_contact_points_of_object(IVP_Real_Object *obj0) {
    while (IVP_Synapse_Friction *syn0 = obj0->get_first_friction_synapse()){
        IVP_Contact_Point *md = syn0->get_contact_point();
	P_DELETE(md);
    }
}



// generates a friction mindist when no one exists. Is there already a friction dist, the old one is returned
IVP_Contact_Point *IVP_Friction_Manager::generate_contact_point(IVP_Mindist *mindist,IVP_BOOL *successful){
  
	//
	// Valid call with non-exact and Ipion forces a write to null to crash in its IVP_ASSERT!
	//

//    IVP_ASSERT(mindist->mindist_status == IVP_MD_EXACT); // already enabled?
    
	if ( mindist->mindist_status != IVP_MD_EXACT )
	{
		*successful = IVP_FALSE;
		return NULL;
	}

    // at this time, only polygon PF is allowed for friction mindists
    // KK: not yet, PP & PK never

    IVP_Contact_Point *already_exists_fmd = get_associated_contact_point(mindist);
    if(already_exists_fmd) {
        *successful=IVP_FALSE;
        return already_exists_fmd;
    }

// make new friction mindist
    IVP_Contact_Point *friction =  new IVP_Contact_Point(mindist);
    //insert_contact_point(friction);
    //printf("insert_nmd %lx\n",(long)friction&0x0000ffff);

    *successful=IVP_TRUE;
    return friction;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -