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

📄 ivp_impact.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 5 页
字号:
      
    IVP_DOUBLE push_v0,push_v1;
    push_v0=0.0f;

    //printf("absolute_velocity %.2f  ",relative_world_speed.real_length());
    
    push_v1= - relative_world_speed.dot_product(surf_normal);

    IVP_DOUBLE u0,u1; //speed results after push
    IVP_DOUBLE div_masses=1.0f/(virt_mass[0]+virt_mass[1]);

    //not maximal fast
    u0=(2.0f*virt_mass[1]*push_v1+push_v0*(virt_mass[0]-virt_mass[1]));
    u1=(2.0f*virt_mass[0]*push_v0+push_v1*(virt_mass[1]-virt_mass[0]));
    u0*=div_masses;
    u1*=div_masses;

    IVP_DOUBLE diff_v0=u0-push_v0;
    //IVP_DOUBLE diff_v1=u1-push_v1; //difference of velocity before/after impact

    IVP_IF(core[0]->environment->debug_information->debug_impact)
    {
	printf("start_impulse %.2f\n",diff_v0*virt_mass[0]);	
    }
    return(diff_v0*virt_mass[0]);    
}

// #+# simplify this function a lot
void IVP_Impact_Solver_Long_Term::do_impact_of_two_objects(IVP_Mindist *mindist,  IVP_Real_Object *obj0, IVP_Real_Object *obj1 )
{
	// coll_point in object_coordinates
	// surface_normal in world_coords

	// environment->debug_information->psi_synchrone=1;

	// mindist->synapse[0]->l_obj->to_real()->revive_object_for_simulation();
	// mindist->synapse[1]->l_obj->to_real()->revive_object_for_simulation();

	IVP_Friction_System* affected_friction_system;
	IVP_BOOL having_new_dist;

	IVP_Core *core0 = obj0->get_core();
	IVP_Core *core1 = obj1->get_core();
	IVP_Simulation_Unit *sim_u;
	if( obj0->get_movement_state() >= IVP_MT_NOT_SIM ) {
		sim_u = core0->sim_unit_of_core;
	} else {
		sim_u = core1->sim_unit_of_core;
	}

	IVP_Contact_Point* my_fr_dist = mindist->try_to_generate_managed_friction(&affected_friction_system,&having_new_dist,sim_u,IVP_TRUE); //with recalc_friction_s_vals
	IVP_Impact_Solver_Long_Term* imp_solve = my_fr_dist->tmp_contact_info;

	IVP_Time now_time, last_time;
	IVP_Friction_Core_Pair* pair = affected_friction_system->find_pair_of_cores(core0,core1);
	now_time = mindist->get_environment()->get_current_time();
	last_time = pair->last_impact_time_pair;
	pair->last_impact_time_pair = now_time;
	IVP_Environment* env = mindist->get_environment();

	// printf("impactt\n");
	IVP_Core *impacteers[2];

	IVP_FLOAT rescue_val_addon = my_fr_dist->get_rescue_speed_impact(obj0->get_environment());

	///////////////////////////////////////////////////////////////////////////
	//@@VALVE
	///////////////////////////////////////////////////////////////////////////
	IVP_Event_Collision event_collision;
	event_collision.d_time_since_last_collision = now_time - last_time;
	event_collision.environment = env;
	event_collision.contact_situation = imp_solve; //is inherited
	env->fire_event_pre_collision( &event_collision );
	{
		if (obj0->flags.collision_listener_exists) 
		{
			IVP_Cluster_Manager *clus_man = env->get_cluster_manager();
			clus_man->fire_event_pre_collision(obj0, &event_collision);
		}

		if (obj1->flags.collision_listener_exists) 
		{
			IVP_Cluster_Manager *clus_man = env->get_cluster_manager();
			clus_man->fire_event_pre_collision(obj1, &event_collision);
		}
	}

	imp_solve->do_impact_long_term(impacteers,rescue_val_addon,my_fr_dist);

	IVP_U_Float_Point speed_for_callback;
	speed_for_callback.set(&imp_solve->speed);
	if( core1->physical_unmoveable ) {
		speed_for_callback.mult(-1.0f); //IVP_Impact_Solver_Long_Term changes order when core1 is unmovable @@CB fptodp
	}

//	if((having_new_dist==IVP_FALSE)||1) 
	{
		IVP_Impact_System imp_sys;
		imp_sys.init_and_solve_impact_system(mindist, affected_friction_system, pair, my_fr_dist);
	}

	// copy changed values
	event_collision.contact_situation = imp_solve; //is inherited
	imp_solve->speed.set(&speed_for_callback);
	env->fire_event_post_collision(&event_collision);

	{
		if (obj0->flags.collision_listener_exists) 
		{
			IVP_Cluster_Manager *clus_man = env->get_cluster_manager();
			clus_man->fire_event_post_collision(obj0, &event_collision);
		}

		if (obj1->flags.collision_listener_exists) 
		{
			IVP_Cluster_Manager *clus_man = env->get_cluster_manager();
			clus_man->fire_event_post_collision(obj1, &event_collision);
		}
	}
}


#if 0
    if(0) { //merge example!!
        IVP_Core *core_to_merge=mindist->get_synapse(0)->get_object()->physical_core;
	IVP_Core *other_core0=mindist->get_synapse(1)->get_object()->physical_core;

	if(core_to_merge->physical_unmoveable){
	    IVP_Core *h = core_to_merge; core_to_merge = other_core0; other_core0 = h;
	}
	IVP_ASSERT(core_to_merge->physical_unmoveable == IVP_FALSE);

	IVP_Core *other_core1;
	other_core1=IVP_Impact_Solver_Long_Term::find_second_critical_impact_core(core_to_merge,other_core0);
	
	if(other_core1!=NULL){
	    IVP_Core *best_other_core = IVP_Impact_Solver_Long_Term::get_best_merge_core(core_to_merge,other_core0,other_core1);
	    core_to_merge->create_collision_merged_core_with(best_other_core);
	}
    }
#endif

void IVP_Contact_Point::get_material_info(IVP_Material *mtl[2]) {
    int k;
    for(k=0;k<2;k++) {
    	int mat_index = this->get_synapse(k)->get_material_index();
	if (mat_index == 0){
	    mtl[k] = get_synapse(k)->get_object()->l_default_material;
	}else{
	    IVP_Environment *env = get_synapse(0)->get_object()->get_environment();
	  mtl[k] = env->get_material_manager()->get_material_by_index(0,mat_index);  // @@@@@
	}
	IVP_ASSERT(mtl[k]);
    }
}

void IVP_Impact_Solver::get_cos_sin_for_impact(IVP_FLOAT friction_val,IVP_FLOAT percent_energy_conservation,IVP_FLOAT *cos_val,IVP_FLOAT *sin_val) {
    IVP_DOUBLE impact_fri_fact=friction_val * (1.0f + IVP_Inline_Math::ivp_sqrtf(percent_energy_conservation));
    IVP_DOUBLE fri_angle = IVP_Inline_Math::atand(impact_fri_fact);  // #+# bitter, kill, 
    IVP_DOUBLE c = IVP_Inline_Math::approx5_cos(fri_angle);
    *cos_val = c;
    *sin_val = c * impact_fri_fact;
}


void IVP_Contact_Point::read_materials_for_contact_situation(IVP_Impact_Solver_Long_Term *info) {

    
    IVP_Real_Object *obj0,*obj1;
    obj0 = get_synapse(0)->get_object(); //syn0->get_ivp_polygon();
    obj1 = get_synapse(1)->get_object(); //syn1->get_ivp_polygon();

    get_material_info(info->materials);
    
    IVP_Environment *env = obj0->get_environment();

    //////// IVP_Contact_Situation
    info->objects[0] = obj0;	// IVP_Contact_Situation
    info->objects[1] = obj1;

    info->compact_edges[0] = get_synapse(0)->edge;
    info->compact_edges[1] = get_synapse(1)->edge;


    IVP_ASSERT(obj0 != obj1);    
    IVP_Material_Manager *mtlm = env->get_material_manager();
    
    info->impact.percent_energy_conservation  = mtlm->get_elasticity(info);

    this->real_friction_factor = mtlm->get_friction_factor(info);
}


extern IVP_Mindist *g_pCurrentMindist;
extern bool g_fDeferDeleteMindist;
// assert:	recalc_mindist 	called
// assert:	mindist of EXACT
// actions perform the impact of two real (!) objects with all !!! side effects
// #+# simplify, move synchronize and revive to do_impact_of_two_objects
void IVP_Mindist::do_impact(){
	g_pCurrentMindist = this;
    IVP_Environment *env;
    env=get_environment();
    
    IVP_ASSERT( mindist_status == IVP_MD_EXACT);

    // move variables too impact system
    IVP_Real_Object *objects[2];
    
    for (int i = 0;i<2;i++){
      IVP_Synapse_Real *syn = this->get_synapse(i);
	IVP_Real_Object  *obj= syn->l_obj;
	objects[i] = obj;
	obj->revive_object_for_simulation();
    }

	g_pCurrentMindist = NULL;
	if (g_fDeferDeleteMindist)
	{
		// BUGBUG: someone changed a collision filter and didn't tell us!
		IVP_ASSERT(0);
		delete this;
		return;
	}

    //revive_object_core is calling start_memory_transaction and end_memory_transaction, so we cannot start memory transaction earlier
    env->sim_unit_mem->start_memory_transaction();

    for(int j=0;j<2;j++) {
	IVP_Core *core=objects[j]->get_core();
	if ( IVP_MTIS_SIMULATED(core->movement_state) && !core->pinned){ //@@CB
	  core->synchronize_with_rot_z();
	}	
    }    
    
    env->mindist_event_timestamp_reference++;

    IVP_Impact_Solver_Long_Term::do_impact_of_two_objects(this, objects[0], objects[1]   );
    env->sim_unit_mem->end_memory_transaction();
}

//find second critical core for core0 that is not core1
IVP_Core *IVP_Impact_Solver_Long_Term::find_second_critical_impact_core(IVP_Core *core0,IVP_Core *core1)
{
    
    for(int c= core0->objects.len()-1;c>=0; c--){
	IVP_Real_Object *r_obj=core0->objects.element_at(c);
	for(IVP_Synapse_Real *synr=r_obj->get_first_exact_synapse();synr;synr=synr->get_next())
	{
	    IVP_Mindist *mdist=synr->get_mindist();
	    //if(mdist->coll_watcher.nr_collisions_per_psi>4) {
	    if(1) { //change that!
		for(int i=0;i<2;i++) {
		    IVP_Synapse_Real *syn;
		    syn=mdist->get_synapse(i);
		   IVP_Real_Object *obj=syn->get_object();
		   if((obj->physical_core!=core0)&&(obj->physical_core!=core1)) {
		       return obj->physical_core;
		   }
		}
	    }
	}	
    }
    return NULL;
}

//merge (movable) core0 with core1 or core2. return best alternative
IVP_Core *IVP_Impact_Solver_Long_Term::get_best_merge_core(IVP_Core *core0,IVP_Core *core1,IVP_Core *core2)
{
    IVP_Friction_Info_For_Core *fr_i=core0->moveable_core_has_friction_info();
    if(!fr_i) {
	return core1; //friction is disabled 
    }
    IVP_Friction_System *fr_sys=fr_i->l_friction_system;

    int anz_1=0;
    int anz_2=0;
    for (int i = fr_sys->fr_pairs_of_objs.len()-1; i>=0;i--){
	IVP_Friction_Core_Pair *my_pair = fr_sys->fr_pairs_of_objs.element_at(i);
	int my_1_nr;
	if(my_pair->objs[0]==core0){
	    my_1_nr=1;
	} else {
	    my_1_nr=0;
	}
	if(my_pair->objs[my_1_nr]==core1){
	    anz_1=my_pair->number_of_pair_dists();
	}
	if(my_pair->objs[my_1_nr]==core2)	{
	    anz_2=my_pair->number_of_pair_dists();
	}
    }
    if(anz_2>anz_1) {
	return core2;
    } else {
	return core1;
    }
}


void IVP_Impact_Solver_Long_Term::do_impact_long_term(IVP_Core *pushed_cores[2],IVP_FLOAT rescue_speed_val,IVP_Contact_Point *cp)
{
    IVP_Impact_Solver imp_solver_stack;
    IVP_U_Float_Point surf_normal_stack; 
    if(!contact_core[1]) {

	imp_solver_stack.core[0] = objects[1]->get_core();
	imp_solver_stack.core[1] = contact_core[0];
	
	imp_solver_stack.obj_point[0]=&contact_point_cs[1];
	imp_solver_stack.obj_point[1]=&contact_point_cs[0];
	surf_normal_stack.set_negative(&surf_normal);
	imp_solver_stack.surf_normal=&surf_normal_stack;
    } else {
	imp_solver_stack.core[0]=contact_core[0];
	if (!contact_core[0]){
	    imp_solver_stack.core[0] = objects[0]->get_core();
	}
	imp_solver_stack.core[1]=contact_core[1];
	imp_solver_stack.obj_point[0]=&contact_point_cs[0];
	imp_solver_stack.obj_point[1]=&contact_point_cs[1];
	imp_solver_stack.surf_normal=&surf_normal;
    }
    imp_solver_stack.speed=&speed; //return value
    imp_solver_stack.percent_energy_conservation = this->impact.percent_energy_conservation;
    imp_solver_stack.two_friction_values=IVP_FALSE;

	if ( imp_solver_stack.core[0]->car_wheel || imp_solver_stack.core[1]->car_wheel ) {
		imp_solver_stack.get_cos_sin_for_impact(0.0f, this->impact.percent_energy_conservation,&imp_solver_stack.cos_friction,&imp_solver_stack.sin_friction);
	}else{
		imp_solver_stack.get_cos_sin_for_impact(cp->real_friction_factor, this->impact.percent_energy_conservation,&imp_solver_stack.cos_friction,&imp_solver_stack.sin_friction);
		if(cp->two_friction_values) {
		imp_solver_stack.get_world_direction_second_friction(cp);//imp_solver_stack.two_friction_values=cp->get_world_direction_second_friction(&imp_solver_stack.world_direction_second_friction,&imp_solver_stack.sin_second_friction);
		}
	}
    IVP_IF(1) {
	if (contact_core[0]) contact_core[0]->core_plausible_check();
	if (contact_core[1]) contact_core[1]->core_plausible_check();

⌨️ 快捷键说明

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