📄 ivp_controller_stiff_spring.cxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
#include <ivp_physics.hxx>
#ifndef WIN32
# pragma implementation "ivp_controller_stiff_spring.hxx"
#endif
#include <ivp_solver_core_reaction.hxx>
#include <ivp_actuator.hxx>
#include <ivp_controller_stiff_spring.hxx>
//////////////////////////
IVP_Template_Stiff_Spring::IVP_Template_Stiff_Spring(){
P_MEM_CLEAR(this);
this->break_max_len = P_FLOAT_MAX;
}
IVP_Template_Stiff_Spring_Active::IVP_Template_Stiff_Spring_Active(){
active_float_spring_len = NULL;
active_float_spring_constant = NULL;
active_float_spring_damp = NULL;
}
/////////////////// SPRING /////////////////
IVP_CONTROLLER_PRIORITY IVP_Controller_Stiff_Spring::get_controller_priority(){
return IVP_CP_STIFF_SPRINGS;
}
void IVP_Controller_Stiff_Spring::fire_event_spring_broken(){
for (int i = listeners_spring_event.len()-1; i>=0; i--){
IVP_Listener_Stiff_Spring *li = listeners_spring_event.element_at(i);
li->event_stiff_spring_broken(this);
}
}
IVP_Controller_Stiff_Spring::IVP_Controller_Stiff_Spring(IVP_Environment *env, IVP_Template_Stiff_Spring *spring_templ )
: IVP_Actuator_Two_Point(env, spring_templ, IVP_ACTUATOR_TYPE_STIFF_SPRING){
this->spring_len = spring_templ->spring_len;
this->break_max_len = spring_templ->break_max_len;
this->max_len_exceed_type = spring_templ->max_len_exceed_type;
this->l_environment=env;
// set mass adapted spring constant
this->spring_constant = spring_templ->spring_constant;
this->spring_damp = spring_templ->spring_damp;
}
void IVP_Controller_Stiff_Spring::set_len(IVP_DOUBLE len){
if (spring_len == len) return;
spring_len = len;
this->ensure_actuator_in_simulation();
}
void IVP_Controller_Stiff_Spring::set_break_max_len(IVP_DOUBLE len){
if (break_max_len == len) return;
break_max_len = len;
this->ensure_actuator_in_simulation();
}
void IVP_Controller_Stiff_Spring::set_constant(IVP_DOUBLE c){
spring_constant = c;
this->ensure_actuator_in_simulation();
}
void IVP_Controller_Stiff_Spring::set_damp(IVP_DOUBLE c){
spring_damp = c;
this->ensure_actuator_in_simulation();
}
IVP_Controller_Stiff_Spring::~IVP_Controller_Stiff_Spring()
{
}
void IVP_Controller_Stiff_Spring_Active::active_float_changed(IVP_U_Active_Float *af){
if (af == active_float_spring_len){
set_len( af->get_float_value());
return;
}
if (af == active_float_spring_constant){
set_constant( af->get_float_value());
return;
}
if (af == active_float_spring_damp){
set_damp( af->get_float_value());
return;
}
CORE;
}
IVP_Controller_Stiff_Spring_Active::IVP_Controller_Stiff_Spring_Active(IVP_Environment *env,
IVP_Template_Stiff_Spring_Active *spring_templ)
: IVP_Controller_Stiff_Spring(env,spring_templ){
active_float_spring_len = spring_templ->active_float_spring_len;
active_float_spring_constant = spring_templ->active_float_spring_constant;
active_float_spring_damp = spring_templ->active_float_spring_damp;
if (active_float_spring_len){
active_float_spring_len->add_dependency(this);
spring_len = active_float_spring_len->get_float_value();
}
if (active_float_spring_constant){
active_float_spring_constant->add_dependency(this);
spring_constant = active_float_spring_constant->get_float_value();
}
if (active_float_spring_damp){
active_float_spring_damp->add_dependency(this);
spring_damp = active_float_spring_damp->get_float_value();
}
}
IVP_Controller_Stiff_Spring_Active::~IVP_Controller_Stiff_Spring_Active(){
if (active_float_spring_len){
active_float_spring_len->remove_dependency(this);
}
if (active_float_spring_constant){
active_float_spring_constant->remove_dependency(this);
}
if (active_float_spring_damp){
active_float_spring_damp->remove_dependency(this);
}
}
void IVP_Controller_Stiff_Spring::do_simulation_controller(IVP_Event_Sim *es,IVP_U_Vector<IVP_Core> * /*core_list*/) {
/* first step: collect all data */
IVP_U_Float_Point dir_ws;
IVP_U_Point pos0_ws;
IVP_DOUBLE dlen;
IVP_Anchor *anch0 = this->get_actuator_anchor(0);
IVP_Anchor *anch1 = this->get_actuator_anchor(1);
IVP_Core *pc0 = anch0->l_anchor_object->get_core();
IVP_Core *pc1 = anch1->l_anchor_object->get_core();
{
IVP_U_Point pos1_ws;
pc0->get_m_world_f_core_PSI()->vmult4( &anch0->core_pos, &pos0_ws);
pc1->get_m_world_f_core_PSI()->vmult4( &anch1->core_pos, &pos1_ws);
dir_ws.subtract(&pos0_ws,&pos1_ws); //force direction world coords
dlen = dir_ws.real_length_plus_normize();
if (dlen < P_FLOAT_EPS){
return;
}
if (dlen > break_max_len){
switch(max_len_exceed_type){
case IVP_SFE_BREAK:
fire_event_spring_broken();
P_DELETE_THIS(this);
return;
default:
;
}
}
}
if (pc0->movement_state >= IVP_MT_NOT_SIM) pc0 = NULL;
if (pc1->movement_state >= IVP_MT_NOT_SIM) pc1 = NULL;
/* second step: calc and apply forces */
IVP_Solver_Core_Reaction scr;
scr.init_reaction_solver_translation_ws( pc0, pc1, pos0_ws, &dir_ws, NULL, NULL);
IVP_U_Matrix3 &tpm = scr.m_velocity_ds_f_impulse_ds;
IVP_DOUBLE a = (this->spring_len - dlen) * es->i_delta_time * this->spring_constant -
scr.delta_velocity_ds.k[0] * ( this->spring_constant + this->spring_damp * ( 1.0f - this->spring_constant));
IVP_U_Float_Point impulses;
impulses.k[0] = a / tpm.get_elem(0,0) ;
scr.exert_impulse_dim1(pc0, pc1, impulses);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -