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

📄 ivp_impact.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 5 页
字号:
    }
    imp_solver_stack.do_impact(pushed_cores,IVP_TRUE,impacts_while_system,rescue_speed_val);
    IVP_IF(1) {
	if (contact_core[0]) contact_core[0]->core_plausible_check();
	if (contact_core[1]) contact_core[1]->core_plausible_check();
    }
}

//call recalc_friction_s_vals for all fr_dists except the initial one
//is nearly same as check_all_fr_mindists_to_be_valid
//->make redesign !!!!!
void IVP_Impact_System::impact_system_check_start_pair(IVP_Friction_Core_Pair *start_pair,IVP_Contact_Point *mdfr) {
    
    for (int i = start_pair->fr_dists.len()-1; i>=0;i--){
	IVP_Contact_Point *my_dist = start_pair->fr_dists.element_at(i);
	if( mdfr != my_dist ) { // warning old version checked mdfr !=  next_dist
	    my_dist->recalc_friction_s_vals();
	    IVP_Impact_Solver_Long_Term *info=my_dist->tmp_contact_info;
	    my_dist->read_materials_for_contact_situation(info);
	    //printf("impact_sys_update_contact_vals %lx\n",(long)my_dist);
	    if(info->friction_is_broken==IVP_TRUE) {
	        associated_fs_system->delete_friction_distance(my_dist);
	    }
	}
    }
    
}

// optimize: first (initial) friction mindist is checked although it is known that it is valid

// Impact System:
// An Impact System is oriented to the Friction System. Friction Mindists are checked if 
// they are still valid and then if they may collide in the near future. If they do, the 
// impact is done instantly for speedup. 
//
// There are three lists. One list with interesting Mindists. One list with Cores that are 
// known (means they are synchronized for that point in time) and one list with Cores that 
// have already impacted (they are synchronized and their speed has changed, meaning their 
// Exact_Mindists and their Next_PSI_Matrix have to be updated. More speedup is gained with 
// delaying technique. A core that is pushed only very weak doesnt change its speed. The 
// speed is added in next PSI. Delayed cores need no update in Exact_Mindists and 
// Next_PSI_Matrix. But the synchronize has to be undone. Delayed cores are found in list 
// with known cores, but not necessarily in list with pushed cores. When a push is done in 
// Impact System, the pushed cores (not a delayed one) are taken and their Mindists are 
// rechecked (calc_coll_distance). A Core that was pushed is put into pushed list. A delayed 
// push means that Mindists dont need call to calc_coll_distance. When everything is over, 
// the cores beeing in known list and NOT beeing in pushed list are unsynchronized. All 
// Cores in pushed list are updated in Exact_Mindists and Next_PSI_Matrix.

// #+# these things with start_pair and except_pair are weird and not necessary any longer: 
// remove
void IVP_Impact_System::init_and_solve_impact_system(IVP_Mindist *mindist, IVP_Friction_System *fs_system,IVP_Friction_Core_Pair *start_pair,IVP_Contact_Point *start_fr_dist)
{
    IVP_Core *start_core0=start_fr_dist->get_synapse(0)->get_object()->get_core();
    IVP_Core *start_core1=start_fr_dist->get_synapse(1)->get_object()->get_core();
  
    sum_of_pushes=0;
    associated_fs_system=fs_system;
    l_environment=start_pair->objs[0]->environment;

    IVP_Core *core0,*core1;
    
    if(start_core0 && !start_core0->physical_unmoveable && !start_core0->pinned) { //@@CBPIN
	add_pushed_core_with_pairs_except(start_core0,start_pair);
	//invalidate_impact_mindists(start_core0);
    }

    core0 = start_pair->objs[0];//start_mindist->synapse[0]->get_core();
    if(!core0->physical_unmoveable  && !core0->pinned) { //@@CBPIN
	add_known_core_to_impact_system(core0);
    }
       
    if(start_core1 && !start_core1->physical_unmoveable && !start_core1->pinned) { //@@CBPIN
	add_pushed_core_with_pairs_except(start_core1,start_pair);
	//invalidate_impact_mindists(start_core1);
    }
    
    core1 = start_pair->objs[1];//start_mindist->synapse[1]->get_core();    
    if(!core1->physical_unmoveable && !core1->pinned) { //@@CBPIN
	add_known_core_to_impact_system(core1);
    }

    add_pair_to_impact_system(start_pair);
    impact_system_check_start_pair(start_pair,start_fr_dist);
    
    IVP_IF(1) {
        l_environment->get_debug_manager()->debug_imp_sys=IVP_FALSE;
    }
    
    IVP_IF(l_environment->get_debug_manager()->file_out_impacts) {
        if(l_environment->get_current_time().get_time() > 10000.86f) {
	    printf("critical_imp_sys\n");
	    l_environment->get_debug_manager()->debug_imp_sys=IVP_TRUE;
	}
        fprintf(l_environment->get_debug_manager()->out_deb_file,"starting_impact_system at time %f\n",l_environment->get_current_time().get_time());
    }

    int impact_sys_counter = 0;
    while(test_loop_all_pairs()==IVP_TRUE)    {
	impact_sys_counter ++;
	sum_of_pushes++;
	if(sum_of_pushes > MAXIMUM_SYSTEM_PUSH_NUMBER) {
	    IVP_IF(1) {
		printf("system_push_number exceeded\n");
	    }
	    P_DELETE(mindist);
	    break;
	    // put some mindists into hull!
	}
    }
    l_environment->get_statistic_manager()->impact_sum_sys+= impact_sys_counter+1;

    IVP_IF(sum_of_pushes>1) {
	//printf("did_impact_sys %d pushes at %f\n",sum_of_pushes,l_environment->get_current_time());
#if 0
	for(IVP_Friction_Core_Pair *my_pair=get_first_impact_pair();my_pair;my_pair=get_next_impact_pair())
	{
	    printf(" paair %lx ",(long)my_pair&0x0000ffff);
	    for(IVP_Contact_Point *my_fr=my_pair->get_first_fr_dist_obj_pairs();my_fr;my_fr=my_pair->get_next_fr_dist_obj_pairs())
	    {
		printf("md %lx ",(long)my_fr&0x0000ffff);
	    }
	}
	printf("\n");
#endif
    }
    IVP_IF(1) {
        debug_check_all_dists_at_end();
    }
    
    recalc_all_affected_cores();
    IVP_IF(1) {
	associated_fs_system->debug_clean_tmp_info();
    }
    IVP_IF(l_environment->get_debug_manager()->file_out_impacts) {
	l_environment->get_debug_manager()->debug_imp_sys=IVP_FALSE;	
        fprintf(l_environment->get_debug_manager()->out_deb_file,"\n");
    }
}

void IVP_Impact_System::add_pair_to_impact_system(IVP_Friction_Core_Pair *new_pair)
{
    i_s_pairs.add(new_pair);
#if 0 /* this is done now at recalc_friction_s_vals */   
    for (int i = new_pair->fr_dists.len()-1; i>=0; i--){
	IVP_Contact_Point *my_dist = new_pair->fr_dists.element_at(i);
	my_dist->tmp_contact_info->rescue_factor=1.0f;
	my_dist->tmp_contact_info->impacts_while_system=0;
	my_dist->tmp_contact_info->coll_time_is_valid=IVP_FALSE;
    }
#endif    
}

void IVP_Impact_System::synchronize_core_for_impact_system(IVP_Core *new_core) {
    if (IVP_MTIS_SIMULATED( new_core->movement_state )){
	new_core->synchronize_with_rot_z();
    }
}

void IVP_Impact_System::add_pushed_core_with_pairs_except(IVP_Core *new_core,IVP_Friction_Core_Pair *start_pair)
{
    add_pushed_core_to_impact_system(new_core);
    
    // connection of core to all its pairs is missing -> loop is quite big, but add_core is not too often done
    for ( int i = associated_fs_system->fr_pairs_of_objs.len()-1; i>=0; i--){
	IVP_Friction_Core_Pair *fr_pair = associated_fs_system->fr_pairs_of_objs.element_at(i);
	if((fr_pair->objs[0] == new_core)  ||   (fr_pair->objs[1] == new_core))	{
	    if(fr_pair!=start_pair) {
		if(pair_is_already_in_system(fr_pair)==IVP_FALSE) {
		    if(fr_pair->check_all_fr_mindists_to_be_valid(this->associated_fs_system) > 0) {
			//warning: at this point fr_pair could be deleted
			add_pair_to_impact_system(fr_pair);
		    }
		}
	    }
	}
    }
}



// speedup: put flag in pairs
IVP_BOOL IVP_Impact_System::pair_is_already_in_system(IVP_Friction_Core_Pair *test_pair) {
    for (int i = i_s_pairs.len()-1; i>=0; i--){
	IVP_Friction_Core_Pair *my_pair = i_s_pairs.element_at(i);
	if(my_pair==test_pair) {
	    return IVP_TRUE;
	}
    }
    return IVP_FALSE;
}

void IVP_Friction_System::debug_clean_tmp_info() {
    IVP_Contact_Point *my_dist;
    for(my_dist=this->get_first_friction_dist();my_dist;my_dist=this->get_next_friction_dist(my_dist)) {
	my_dist->tmp_contact_info=NULL;
    }
}

void IVP_Impact_System::debug_check_all_dists_at_end() {
    IVP_Contact_Point *my_dist;
    for(my_dist=associated_fs_system->get_first_friction_dist();my_dist;my_dist=associated_fs_system->get_next_friction_dist(my_dist)) {
	my_dist->recalc_friction_s_vals();
	my_dist->calc_coll_distance();
	my_dist->tmp_contact_info->coll_time_is_valid=IVP_FALSE;
	if(my_dist->tmp_contact_info->impact.distance_reached_in_time < ivp_mindist_settings.minimum_friction_dist) {
	    IVP_Core *core0,*core1;
	    core0=my_dist->get_synapse(0)->get_object()->physical_core;
	    core1=my_dist->get_synapse(1)->get_object()->physical_core;

	    int unmov0,unmov1;
	    unmov0=(int)core0->physical_unmoveable | (int)core0->temporarily_unmovable;
	    unmov1=(int)core1->physical_unmoveable | (int)core1->temporarily_unmovable;
	    if(unmov0&unmov1) {
		continue;
	    }
	    if(core_is_already_known_to_system(core0) && core_is_already_known_to_system(core1)) {
		printf("error_in_impact_system_missed_impact\n");
	    }
	}
    }
}

IVP_BOOL IVP_Impact_System::test_loop_all_pairs()
{
#ifndef SYSTEM_IMPACT_ENABLED
    return IVP_FALSE;
#endif
    
    IVP_Contact_Point *worst_impact_dist=NULL;
    IVP_Friction_Core_Pair *associated_pair = NULL;
    IVP_DOUBLE smallest_distance =  ivp_mindist_settings.minimum_friction_dist;
    IVP_DOUBLE rescue_speed_addon=0.0f;
    IVP_IF(l_environment->get_debug_manager()->file_out_impacts) {
        fprintf(l_environment->get_debug_manager()->out_deb_file,"calc_new_coll_distances\n");
    }
    for (int i = i_s_pairs.len()-1; i >= 0 ; i--){
	IVP_Friction_Core_Pair *my_pair = i_s_pairs.element_at(i);
	int unmov0,unmov1;
	unmov0=(int)my_pair->objs[0]->physical_unmoveable | (int)my_pair->objs[0]->temporarily_unmovable; //@@CBPIN
	unmov1=(int)my_pair->objs[1]->physical_unmoveable | (int)my_pair->objs[1]->temporarily_unmovable; //@@CBPIN
	if(unmov0 & unmov1) {
	    continue;
	}
	for (int k = my_pair->fr_dists.len()-1; k>=0; k--){
	    IVP_Contact_Point *my_fr = my_pair->fr_dists.element_at(k);
	    if(my_fr->tmp_contact_info->coll_time_is_valid==IVP_TRUE) {
	      IVP_IF(l_environment->get_debug_manager()->debug_imp_sys) {
		printf("did_not_test %lx\n",0x0000ffff&(long)my_fr);
	      }
	    } else {
		l_environment->get_statistic_manager()->impact_coll_checks++;
		my_fr->calc_coll_distance();
	    }
	    if(my_fr->tmp_contact_info->impact.distance_reached_in_time< smallest_distance ) {
		rescue_speed_addon=my_fr->tmp_contact_info->impact.rescue_speed_addon;
		smallest_distance=my_fr->tmp_contact_info->impact.distance_reached_in_time;
		worst_impact_dist=my_fr;
		associated_pair=my_pair;
	    }
	}
    }
    IVP_IF(l_environment->get_debug_manager()->file_out_impacts) {
        fprintf(l_environment->get_debug_manager()->out_deb_file,"\n");
    }
    
    if(worst_impact_dist){
	IVP_ASSERT(worst_impact_dist->tmp_contact_info->impact.distance_reached_in_time < ivp_mindist_settings.minimum_friction_dist);
	IVP_Core *core;
	for(int i=1;i>=0;i--) {
	    core=worst_impact_dist->tmp_contact_info->contact_core[i];
	    if(core) {
		if(core_is_already_known_to_system(core)==IVP_FALSE) {
		// Mac port was: if (i_s_known_cores.index_of(core) == -1) {
		    add_known_core_to_impact_system(core);
		    synchronize_core_for_impact_system(core);
		}
	    }
	}
	    
	IVP_Core *impacting_cores[2];
	worst_impact_dist->tmp_contact_info->impacts_while_system++;
       
	worst_impact_dist->tmp_contact_info->do_impact_long_term(impacting_cores,worst_impact_dist->tmp_contact_info->impact.rescue_speed_addon,worst_impact_dist);
	    
	//printf("did_sys_imp %lx\n",(long)(&worst_impact_dist->long_term_impact_info)&0x0000ffff);
	    
	{
	    for(int i=1;i>=0;i--) {
		core = impacting_cores[i];
		if(core && !core->physical_unmoveable && !core->pinned) { //@@CBPIN
		    if(core_was_already_pushed_in_system(core)==IVP_FALSE) {
			add_pushed_core_with_pairs_except(core,associated_pair);
		    } else {
			invalidate_impact_mindists(core);
		    }
		}
	    }
	}
	
	return IVP_TRUE;
    } else {
	return IVP_FALSE;
    }
}

void IVP_Impact_System::invalidate_impact_mindists(IVP_Core *my_core)
{    //there is a cheaper way: via synapses
    IVP_Friction_Info_For_Core *my_info = my_core->get_friction_info(associated_fs_system);
    for (int i = my_info->friction_springs.len()-1; i>=0; i--){
	IVP_Contact_Point *my_dist = my_info->friction_springs.element_at(i);
	my_dist->tmp_contact_info->coll_time_is_valid=IVP_FALSE;
    }
}
//direction of second friction lies orthogonal to surf_normal
//returns TRUE when second friction value is used
// &imp_solver_stack.world_direction_second_friction,&imp_solver_stack.sin_second_friction
void  IVP_Impact_Solver::get_world_direction_second_friction(IVP_Contact_Point *cp) { //IVP_U_Float_Point *ret_second_friction_vec,IVP_FLOAT *sin_second_friction) {
    IVP_Material *mtl[2];
    cp->get_material_info(mtl);

    IVP_U_Float_Point *ret_second_friction_vec=&world_direction_second_friction;
    
    IVP_BOOL use_second_friction=IVP_FALSE;

    int i;
    for(i=0;i<2;i++) {
        if(mtl[i]->second_friction_x_enabled) {
#if 1	    
	      //following is copy-paste from function 'two_values_friction'
	      //-> maybe make common structure and fill it
		IVP_U_Float_Point x_direction;
		IVP_Core *i_core=cp->get_synapse(i)->l_obj->friction_core;
		IVP_U_Matrix *mat=

⌨️ 快捷键说明

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