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

📄 ivp_controller_buoyancy.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 2 页
字号:
			//weighted_new_input->set_time_stamp(current_time);
			//solution_values->set_time_stamp(current_time);
			if(!(temp_buoyancy->insert_extrapol_only)) {
			    ai->mi->add_new_input_solution_combination_stochastic(weighted_new_input, solution_values);
			}

			//extrapolate into the future
			IVP_RETURN_TYPE success = calculate_future_extrapolation(&ai->last_io_vectors,
										 weighted_new_input,
										 solution_values,
										 d_time,
										 current_time,
										 future_input,
										 future_solution);
			if (success) {
			    future_input->set_time_stamp(current_time);
			    future_solution->set_time_stamp(current_time);
			    ai->mi->add_new_input_solution_combination_stochastic(future_input, future_solution);
			}
		    }

		    break;
    }
    case IVP_FALSE: {
	//weighted_new_input->set_time_stamp(current_time);
	//solution_values->set_time_stamp(current_time);
	if(!(temp_buoyancy->insert_extrapol_only)) {
	    ai->mi->add_new_input_solution_combination_conventional(weighted_new_input, solution_values);
	}
	    
	//extrapolate into the future
	IVP_RETURN_TYPE success = calculate_future_extrapolation(&ai->last_io_vectors,
								 weighted_new_input,
								 solution_values,
								 d_time,
								 current_time,
								 future_input,
								 future_solution);
	if (success) {
	    future_input->set_time_stamp(current_time);
	    future_solution->set_time_stamp(current_time);
	    ai->mi->add_new_input_solution_combination_conventional(future_input, future_solution);
	}
	break;
    }
	
    } //end switch statement
    
#if 0
    if (ai->mi->get_nr_occupied() < ai->mi->get_nr_of_vectors()) {
	//the array of input vectors in the multidim. interpolator is not yet fully occupied
	ai->mi->add_new_input_solution_combination_conventional(new_input, solution_values);
    } else {
	//array of input vectors is already fully occupied, so a member has to be replaced by a new one
	ai->mi->add_new_input_solution_combination_stochastic(new_input, solution_values);
    }
#endif    
    }
    
    
    
/********************************************************************
 * Name:        do_simulation_controller(...)
 * Description: Simulates the fluid dynamics in the current PSI step
 *              for the core in its class variable 'core'
 * Note:        do_simulation_controller is called by the internal
 *              simulation unit of the physics engine
 ********************************************************************/
void IVP_Controller_Buoyancy::do_simulation_controller(IVP_Event_Sim *es,IVP_U_Vector<IVP_Core> *) {

    IVP_Environment *environment = es->environment;
    IVP_U_Float_Hesse surface_hesse_ws;
    IVP_U_Float_Point abs_speed_of_current_ws;

    //calc the surface of the medium the current core (perhaps) lies in
    attacher_buoyancy->liquid_surface_descriptor->calc_liquid_surface( environment, core, &surface_hesse_ws, &abs_speed_of_current_ws );

    // if area is increased, reduce mean velocity of water
    if (core_visible_surface_content_under > core_visible_surface_content_under_old) {
	relative_speed_of_current_in_objects_vicinity_old.mult(core_visible_surface_content_under_old / core_visible_surface_content_under);
    }

    //update core_visible_surface_content_under(_old)
    core_visible_surface_content_under_old = core_visible_surface_content_under;
    core_visible_surface_content_under = 0.0f;

    
    //calc resulting_speed_of_current
    IVP_U_Float_Point resulting_speed_of_current_ws;
#ifdef DAMPENING_WITH_PARTICLE_ACCELERATION
    resulting_speed_of_current_ws.set(&abs_speed_of_current_ws);
    resulting_speed_of_current_ws.add(&relative_speed_of_current_in_objects_vicinity_old);
#else
    resulting_speed_of_current_ws.set(&abs_speed_of_current_ws);
#endif
    IVP_U_Float_Point rel_speed_of_current_ws;
    rel_speed_of_current_ws.subtract(&resulting_speed_of_current_ws, &core->speed);

    IVP_Template_Buoyancy *temp_buoyancy = attacher_buoyancy->get_parameters_per_core( core);
    
    /*** calc buoyancy and dampening for every object in the core ***/

    int nr_of_objects = core->objects.len();

    for(int i=0; i<nr_of_objects; i++) {
	
	IVP_U_Float_Point rel_speed_of_current_os;
	IVP_U_Float_Hesse surface_os;  //surface in object's coordinate system
	{
	//calc surface_os
	    //translate resulting_speed_of_current_ws into object coordinate system
	    IVP_Cache_Object *cache_object = attacher_interpolator[i].object->get_cache_object_no_lock();
	    cache_object->transform_vector_to_object_coords(&rel_speed_of_current_ws, &rel_speed_of_current_os);
	    cache_object->transform_vector_to_object_coords(&surface_hesse_ws, &surface_os);
	    IVP_U_Matrix m_world_f_object;
	    attacher_interpolator[i].object->get_m_world_f_object_AT(&m_world_f_object);
	    IVP_DOUBLE dist = m_world_f_object.get_position()->dot_product(&surface_hesse_ws);
	    surface_os.hesse_val = surface_hesse_ws.hesse_val + dist;
	}

	//create new input vector without using weights, needed for the buoyancy solver
	IVP_Buoyancy_Input b_input;
	//IVP_MI_Vector *new_input = (IVP_MI_Vector *)&b_input;
	b_input.rel_speed_of_current_os.set(&rel_speed_of_current_os);
	b_input.surface_os.set(&surface_os);
	b_input.surface_os.hesse_val = surface_os.hesse_val;
	b_input.rot_speed.set(&core->rot_speed);

	//create new input vector and use the provided weights
	IVP_Buoyancy_Input weighted_b_input;
	IVP_MI_Vector *weighted_new_input = (IVP_MI_Vector *)&weighted_b_input;
	weighted_b_input.rel_speed_of_current_os.set_multiple(&rel_speed_of_current_os, temp_buoyancy->mi_weights.weight_current_speed);
	weighted_b_input.surface_os.set_multiple(&surface_os, temp_buoyancy->mi_weights.weight_surface);
	weighted_b_input.surface_os.hesse_val = surface_os.hesse_val * temp_buoyancy->mi_weights.weight_surface;
	weighted_b_input.rot_speed.set_multiple(&core->rot_speed, temp_buoyancy->mi_weights.weight_rot_speed);

	//reserve memory on the stack for the new solutions
	IVP_Buoyancy_Output b_output;
	IVP_MI_Vector *solution_values = (IVP_MI_Vector *)&b_output;
	
#if !defined(IVP_NO_MD_INTERPOLATION)
	//check if interpolation should be used or not
	if (temp_buoyancy->use_interpolation) {   //use interpolation
	    IVP_RETURN_TYPE result;

	    //force a new buoyancy solver run if the interpolation_counter has reached the maximum value allowed
	    if (interpolation_counter++ >= temp_buoyancy->max_interpolation_tries) {
		result = IVP_FAULT;          //force new buoyancy_solver run
		interpolation_counter = 0;   //reinitialize counter
	    } else {
		result = attacher_interpolator[i].mi->check_interpolation(weighted_new_input,
									  temp_buoyancy->max_tries_nr_of_vectors_involved,
									  temp_buoyancy->max_res,
									  solution_values);
	    }

	    if (result) {
		//interpolation was successful
		//fetch new solution values

#ifdef WITH_DEBUG_OUTPUT
		printf("Interpolated!\n");
		ivp_debug_show_real_values(&b_input,
					   temp_buoyancy,
					   core,
					   attacher_interpolator->object,
					   &resulting_speed_of_current_ws);
		attacher_interpolator[i].nr_interpolated++;
#endif
	    } else {
		//interpolation failed
		//call the buoyancy solver

#ifdef WITH_DEBUG_OUTPUT
		printf("Not Interpolated!\n");
		attacher_interpolator[i].nr_not_interpolated++;
#endif
		IVP_BOOL in_water = use_buoyancy_solver(&b_input, temp_buoyancy, &b_output, &resulting_speed_of_current_ws, i);
		if (in_water) {
		    //if the buoyancy solver did compute values (if object is in water) then copy the new
		    //input/solution-combination into the interpolator
		    provide_new_input_solution_combination(&attacher_interpolator[i],
							   temp_buoyancy,
							   weighted_new_input,
							   solution_values,
							   es->delta_time,
							   environment->get_current_time());
		}
#ifdef WITH_DEBUG_OUTPUT
		else {
		    printf("Not yet in water!\n");
		}
#endif
	    }
#ifdef WITH_DEBUG_OUTPUT
	    printf("times_interpolated : times_calculated = %d : %d\n", attacher_interpolator[i].nr_interpolated, attacher_interpolator[i].nr_not_interpolated);
	    printf("# of one vector already sufficient = %d\n", attacher_interpolator[i].mi->nr_one_vector_sufficient);
	    for (int q=0; q<attacher_interpolator[i].mi->get_nr_of_vectors(); q++) {
		printf("%d vectors involved:  # of res over limit = %d     ", q+1, attacher_interpolator[i].mi->nr_res_over_limit[q]);
		printf("# of interpol. weigh over limit = %d     ", attacher_interpolator[i].mi->nr_int_weight_over_limit[q]);
		printf("# of times LINFIT failed = %d     ", attacher_interpolator[i].mi->nr_of_linfit_failure[q]);
		printf("# of interpolation successes = %d\n", attacher_interpolator[i].mi->nr_of_success[q]);
	    }
	    printf("\n\n");
#endif

	    //update last_input structure, is needed in 'calculate_future_extrapolation'
	    attacher_interpolator[i].last_io_vectors.last_input_vector->set(weighted_new_input);
	    attacher_interpolator[i].last_io_vectors.last_solution_vector->set(solution_values);
	    //	    attacher_interpolator[i].last_io_vectors.last_psi_time = environment->get_current_time();
	    attacher_interpolator[i].last_io_vectors.last_psi_time = environment->get_current_time().get_time();

	} else {
#endif /* if !defined(IVP_NO_MD_INTERPOLATION) */	
	    //don't use interpolation
	    use_buoyancy_solver(&b_input, temp_buoyancy, &b_output, &resulting_speed_of_current_ws, i);
#ifdef WITH_DEBUG_OUTPUT
	    printf("nr_not_interpolated = %d\n", ++nr_not_interpolated);
#endif
#if !defined(IVP_NO_MD_INTERPOLATION)
	}
#endif	


	//apply the calculated impulses to the current object
	apply_buoyancy_impulse( attacher_interpolator[i].object,
				temp_buoyancy,
				es->delta_time,
				b_output.volume_under,
				&b_output.volume_center_under );

	apply_dampening( attacher_interpolator[i].object,
			 IVP_Inline_Math::fabsd(b_output.object_visible_surface_content_under),
			 es->delta_time,
			 &b_output.sum_impulse_x_movevector,
			 &b_output.sum_impulse_x_point,
			 &b_output.sum_impulse);
	
	//add 'object_visible_surface_content_under' to 'core_visible_surface_content_under'
	//'fabs' is taken in case the interpolation's result was negative
	core_visible_surface_content_under += IVP_Inline_Math::fabsd(b_output.object_visible_surface_content_under);
    }

#ifdef DAMPENING_WITH_PARTICLE_ACCELERATION
    IVP_FLOAT inverse_viscosity = 1.0f - (temp_buoyancy->viscosity_factor * es->delta_time);
    IVP_U_Float_Point speed_of_object_relative_to_medium_ws;
    speed_of_object_relative_to_medium_ws.set(&core->speed);
    speed_of_object_relative_to_medium_ws.subtract(&resulting_speed_of_current_ws);
    
    relative_speed_of_current_in_objects_vicinity_old.mult(inverse_viscosity);
    relative_speed_of_current_in_objects_vicinity_old.add_multiple(&speed_of_object_relative_to_medium_ws, temp_buoyancy->viscosity_input_factor*es->delta_time);
#endif
}



/*********************
 * Constructor
 *********************/
IVP_Controller_Buoyancy::IVP_Controller_Buoyancy(IVP_Attacher_To_Cores<IVP_Controller_Buoyancy> *attacher_buoyancy_, IVP_Core *core_) {
    attacher_buoyancy = (IVP_Attacher_To_Cores_Buoyancy *)attacher_buoyancy_;
    core = core_;
    core->environment->get_controller_manager()->add_controller_to_core(this,core);

    relative_speed_of_current_in_objects_vicinity_old.set(0.0f, 0.0f, 0.0f);
    core_visible_surface_content_under_old = 0.0f;
    core_visible_surface_content_under = 0.0f;

    //initialize vector which applies a multidimensional interpolator to every object in the core
    int nr_of_objects = core->objects.len();

	attacher_interpolator = new Attacher_Interpolator[nr_of_objects];
	for(int i=0; i<nr_of_objects; i++) {
	    attacher_interpolator[i].object = core->objects.element_at(i);
#if !defined( IVP_NO_MD_INTERPOLATION )
	    attacher_interpolator[i].mi = new IVP_Multidimensional_Interpolator(5, INPUT_VECTOR_LENGTH, SOLUTION_VECTOR_LENGTH);
		attacher_interpolator[i].last_io_vectors.last_input_vector = IVP_MI_Vector::malloc_mi_vector(INPUT_VECTOR_LENGTH);
	    attacher_interpolator[i].last_io_vectors.last_solution_vector = IVP_MI_Vector::malloc_mi_vector(SOLUTION_VECTOR_LENGTH);
#endif
	    attacher_interpolator[i].last_io_vectors.last_psi_time = 0;
	    attacher_interpolator[i].nr_interpolated = 0;
	    attacher_interpolator[i].nr_not_interpolated = 0;
	}
    
    interpolation_counter = 0; //initialize the counter

    //for debugging
    nr_not_interpolated = 0;
}



/*********************
 * Destructor
 *********************/
IVP_Controller_Buoyancy::~IVP_Controller_Buoyancy() {
    int nr_of_objects = core->objects.len();
    if ( attacher_interpolator){
	for(int i=0; i<nr_of_objects; i++) {
#if !defined( IVP_NO_MD_INTERPOLATION )
	    P_DELETE(attacher_interpolator[i].mi);
	    //#if !defined(__MWERKS__) || !defined(__POWERPC__)
#pragma message ("this code should not be called")
	    P_DELETE_ARRAY(attacher_interpolator[i].last_io_vectors.last_input_vector);
	    P_DELETE_ARRAY(attacher_interpolator[i].last_io_vectors.last_solution_vector);
	    //#endif
#endif
	}
	P_DELETE_ARRAY(attacher_interpolator); //@@CB was a P_DELETE, which was bad
    }
    
    attacher_buoyancy->attachment_is_going_to_be_deleted(this,core);
    core->environment->get_controller_manager()->remove_controller_from_core(this,core);
}



IVP_Attacher_To_Cores_Buoyancy::IVP_Attacher_To_Cores_Buoyancy(IVP_Template_Buoyancy &templ, IVP_U_Set_Active<IVP_Core> *set_of_cores_, IVP_Liquid_Surface_Descriptor *liquid_surface_descriptor_)
    : IVP_Attacher_To_Cores<IVP_Controller_Buoyancy>(set_of_cores_)
{
    template_buoyancy = templ;
    set_of_cores = set_of_cores_;
    liquid_surface_descriptor = liquid_surface_descriptor_;
};

⌨️ 快捷键说明

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