📄 ivp_sim_unit.cxx
字号:
env->get_sim_units_manager()->rem_sim_unit_from_manager(this);
sim_unit_movement_type=IVP_MT_MOVING;
env->get_sim_units_manager()->add_sim_unit_to_manager(this);
}
}
void IVP_Simulation_Unit::sim_unit_ensure_cores_movement() {
IVP_Core *my_core;
int i;
for(i=sim_unit_cores.len()-1;i>=0;i--) {
my_core=sim_unit_cores.element_at(i);
my_core->reset_freeze_check_values();
}
}
void IVP_Standard_Gravity_Controller::set_standard_gravity(IVP_U_Point *gravity) {
grav_vec.set(gravity);
}
void IVP_Standard_Gravity_Controller::do_simulation_controller(IVP_Event_Sim *es,IVP_U_Vector<IVP_Core> *core_list) {
int i;
for(i=core_list->len()-1;i>=0;i--) {
IVP_Core *my_core=core_list->element_at(i);
if(!my_core->pinned) //@@CB
{
my_core->global_damp_core(es->delta_time);
my_core->commit_all_async_pushes();
my_core->speed.add_multiple( &this->grav_vec,es->delta_time );
}
}
}
void IVP_Simulation_Unit::sim_unit_clear_movement_check_values() {
for (int c = sim_unit_cores.len()-1; c>=0; c--) {
IVP_Core *core = sim_unit_cores.element_at(c);
core->reset_freeze_check_values();
}
}
void IVP_Simulation_Unit::do_sim_unit_union_find() {
this->clean_sim_unit();
this->sim_unit_calc_redundants();
this->perform_test_and_split();
this->union_find_needed_for_sim_unit=IVP_FALSE;
}
IVP_BOOL IVP_Simulation_Unit::sim_unit_calc_movement_state(IVP_Environment *env) {
#if !defined(IVP_DISABLE_FREEZING)
IVP_Movement_Type whole_sys=IVP_MT_CALM;
IVP_Time current_time=env->get_current_time();
for (int c = sim_unit_cores.len()-1; c>=0; c--) {
IVP_Core *core = sim_unit_cores.element_at(c);
core->movement_state=core->calc_movement_state(current_time);
whole_sys=(IVP_Movement_Type)((int)whole_sys & (int)core->movement_state);
}
if( whole_sys == IVP_MT_CALM ) {
for (int n = sim_unit_cores.len()-1; n>=0; n--){
IVP_Core *my_core = sim_unit_cores.element_at(n);
my_core->freeze_simulation_core(); //make callbacks for controllers??
}
env->get_sim_units_manager()->rem_sim_unit_from_manager(this);
this->sim_unit_movement_type=IVP_MT_NOT_SIM;
env->get_sim_units_manager()->add_sim_unit_to_manager(this);
return IVP_TRUE;
}
#endif
return IVP_FALSE;
}
void IVP_Simulation_Unit::init_moving_core_for_psi(IVP_Core *core, const IVP_Time &c_time) {
//IVP_PREFETCH(this->objects.elems); // now using special vector
IVP_IF(1) {
IVP_Friction_Info_For_Core *info=core->moveable_core_has_friction_info();
IVP_Friction_System *fs=NULL;
if(info) {
fs=info->l_friction_system;
}
}
IVP_ASSERT(core->physical_unmoveable==IVP_FALSE);
// IVP_ASSERT ( c_time.get_time() == 0 || IVP_Inline_Math::fabsd( core->time_of_last_psi - c_time + 1.0f / core->i_delta_time ) < 10E-4f);
IVP_DOUBLE d_time = c_time - core->time_of_last_psi;
core->q_world_f_core_next_psi.set_matrix(&core->m_world_f_core_last_psi);
IVP_PREFETCH(core->objects.element_at(0),0);
core->m_world_f_core_last_psi.vv.add_multiple( &core->pos_world_f_core_last_psi, &core->delta_world_f_core_psis, d_time);
}
void IVP_Simulation_Unit::simulate_single_sim_unit_psi(IVP_Event_Sim *es, IVP_U_Vector<IVP_Core> *touched_cores) {
#ifdef DEBUG
IVP_IF(1) {
this->sim_unit_debug_consistency();
}
#endif
es->sim_unit = this;
es->environment->sim_unit_mem->start_memory_transaction();
int controller_num=controller_cores.len();
IVP_Time current_time = es->environment->get_current_time();
int fast_moving_flag = 0;
union {
int fast_moving_core;
float fast_moving_core_p;
}; //warning: 4 Byte of memory are used to store an integer and a float value to get access to sign bit
for (int d = sim_unit_cores.len()-1; d>=1; d--){
IVP_Core *next_core = sim_unit_cores.element_at(d-1);
this->prefetch0_init_moving_core_for_psi(next_core);
IVP_Core *my_core = sim_unit_cores.element_at(d);
this->init_moving_core_for_psi(my_core, current_time);
IVP_IF(1) {
for(int k=my_core->objects.len()-1;k>=0;k--) { IVP_ASSERT(my_core->objects.element_at(k)->get_movement_state()<IVP_MT_NOT_SIM); }
}
my_core->commit_all_async_pushes(); // @@@OS this happens very seldomly !!!!, remove !!!!this necessary as it may happen that core was temporarily_unmovable
// TL: it is also used for delayed pushes and async_pushes
fast_moving_core_p = IVP_OBJECT_MOVING_FAST * IVP_OBJECT_MOVING_FAST - my_core->speed.quad_length();
my_core->temporarily_unmovable = IVP_FALSE;
my_core->impacts_since_last_PSI = 0;
fast_moving_flag |= fast_moving_core;
}
{
IVP_Core *my_core = sim_unit_cores.element_at(0);
this->init_moving_core_for_psi(my_core, current_time);
IVP_IF(1) {
for(int k=my_core->objects.len()-1;k>=0;k--) {
IVP_ASSERT(my_core->objects.element_at(k)->get_movement_state()<IVP_MT_NOT_SIM);
}
}
my_core->commit_all_async_pushes(); // @@@OS this happens very seldomly !!!!, remove !!!!this necessary as it may happen that core was temporarily_unmovable
fast_moving_core_p = IVP_OBJECT_MOVING_FAST*IVP_OBJECT_MOVING_FAST - my_core->speed.quad_length();
my_core->temporarily_unmovable=IVP_FALSE;
my_core->impacts_since_last_PSI=0;
fast_moving_flag |= fast_moving_core;
}
IVP_BOOL check_movement_state;
if( fast_moving_flag < 0 ) {
this->sim_unit_has_fast_objects = IVP_TRUE;
check_movement_state = es->environment->must_perform_movement_check(); //do not always make movement check
// check_movement_state = IVP_FALSE; // this might be wrong if flag is set to IVP_MT_SLOW
} else {
this->sim_unit_just_slowed_down = this->sim_unit_has_fast_objects;
if(sim_unit_just_slowed_down) {
this->sim_unit_clear_movement_check_values();
}
sim_unit_has_fast_objects = IVP_FALSE;
check_movement_state = es->environment->must_perform_movement_check(); //do not always make movement check
}
//controllers are sorted
for(int j=controller_num-1;j>=0;j--) {
IVP_CONTROLLER_PRIORITY debug_contr_prio;
IVP_Controller *my_controller = controller_cores.element_at(j)->l_controller;
IVP_IF(1) {
debug_contr_prio=my_controller->get_controller_priority();
}
my_controller->do_simulation_controller(es,&controller_cores.element_at(j)->cores_controlled_by); //speed dependent, real speed
IVP_IF(1) {
for (int c = sim_unit_cores.len()-1; c>=0; c--) {
IVP_Core *tcore=sim_unit_cores.element_at(c);
tcore->core_plausible_check();
}
}
}
for (int c = sim_unit_cores.len()-1; c>=0; c--) {
IVP_Core *core = sim_unit_cores.element_at(c);
core->calc_next_PSI_matrix(touched_cores, es);
IVP_IF(0) {
core->debug_vec_movement_state();
}
}
if(check_movement_state==IVP_TRUE) {
this->sim_unit_calc_movement_state(es->environment);
}
// #+# find a better solution for invalid mindists (hull is better)
for (int k = sim_unit_cores.len()-1; k>=0; k--){
IVP_Core *my_core = sim_unit_cores.element_at(k);
for(int c = my_core->objects.len()-1;c>=0;c--){
IVP_Real_Object *obj=my_core->objects.element_at(c);
obj->recalc_invalid_mindists_of_object(); // maybe a more lazy approach would be more appropiate
}
}
if(union_find_needed_for_sim_unit) {
do_sim_unit_union_find();
}
es->environment->sim_unit_mem->end_memory_transaction();
}
void IVP_Simulation_Unit::reset_time( IVP_Time offset){
for(int j = controller_cores.len()-1;j>=0;j--) {
IVP_Controller *my_controller = controller_cores.element_at(j)->l_controller;
my_controller->reset_time(offset); //speed dependent, real speed
}
for (int c = sim_unit_cores.len()-1; c>=0; c--) {
IVP_Core *core = sim_unit_cores.element_at(c);
core->reset_time(offset);
}
}
#define prefetch0_simulate_single_sim_unit_psi(this) IVP_PREFETCH_BLOCK(this, sizeof(*this));
#define prefetch1_simulate_single_sim_unit_psi(this ) IVP_IF_PREFETCH_ENABLED(IVP_TRUE){ \
IVP_PREFETCH(this->controller_cores.elems,0); \
IVP_PREFETCH(this->sim_unit_cores.elems,0); }
#define prefetch2_simulate_single_sim_unit_psi(this) IVP_IF_PREFETCH_ENABLED(IVP_TRUE){ \
IVP_PREFETCH(this->controller_cores.element_at(this->controller_cores.len()-1),0); \
IVP_PREFETCH(this->controller_cores.element_at(0),0); \
IVP_PREFETCH(this->sim_unit_cores.element_at( this->sim_unit_cores.len()-1),0); \
this->prefetch0_init_moving_core_for_psi(this->sim_unit_cores.element_at(this->sim_unit_cores.len()-1)); \
}
void IVP_Sim_Units_Manager::simulate_sim_units_psi(IVP_Environment *env, IVP_U_Vector<IVP_Core> *touched_cores) {
IVP_Simulation_Unit *s_u;
IVP_Simulation_Unit *n0_su;
IVP_Simulation_Unit *n1_su;
IVP_Simulation_Unit *n2_su;
IVP_Sim_Units_Manager *sman = this;
IVP_Event_Sim es(env);
s_u = sman->sim_units_slots[0];
if (!s_u) goto sim_units_0;
n0_su = s_u->next_sim_unit;
if (!n0_su) goto sim_units_1;
n1_su = n0_su->next_sim_unit;
if (!n1_su) goto sim_units_2;
n2_su = n1_su->next_sim_unit;
while(n2_su) {
prefetch0_simulate_single_sim_unit_psi(n2_su);
prefetch1_simulate_single_sim_unit_psi(n1_su);
prefetch2_simulate_single_sim_unit_psi(n0_su);
s_u ->simulate_single_sim_unit_psi(&es,touched_cores);
s_u = n0_su;
n0_su = n1_su;
n1_su = n2_su;
n2_su = n2_su->next_sim_unit;
}
prefetch1_simulate_single_sim_unit_psi(s_u);
prefetch2_simulate_single_sim_unit_psi(n0_su);
n1_su ->simulate_single_sim_unit_psi(&es, touched_cores);
sim_units_2:
prefetch2_simulate_single_sim_unit_psi(s_u);
n0_su->simulate_single_sim_unit_psi(&es, touched_cores);
sim_units_1:
s_u ->simulate_single_sim_unit_psi(&es, touched_cores);
sim_units_0:
;
#if 0 && defined(WIN32)
unsigned long time = p_get_time();
//BLOCKING
if( (time > 957460357 /*4may*/ + 60*60*24* (31+26) )) {
IVP_Time now_time=env->get_current_time();
// IVP_BLOCKING
if(this->nb-now_time < 0.0) {
this->nb=now_time+9.73;
IVP_Time_Event_N *n_event=new IVP_Time_Event_N(env->get_current_time());
env->get_time_manager()->insert_event(n_event,env->get_current_time());
P_DELETE(env->get_time_manager()->event_manager);
env->get_time_manager()->event_manager=new IVP_Event_Manager_D();
env->get_time_manager()->event_manager->mode=1;
for(int i=0;i<15;i++) {
IVP_Time_Event_D *d_event=new IVP_Time_Event_D(env->get_current_time());
env->get_time_manager()->insert_event(d_event,env->get_current_time());
}
}
}
#endif
}
void IVP_Sim_Units_Manager::reset_time( IVP_Time offset){
for ( IVP_Simulation_Unit *s = this->sim_units_slots[0];
s;
s = s->next_sim_unit){
s->reset_time(offset);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -