📄 ivp_constraint_fixed_keyed.cxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
// IVP_EXPORT_PROTECTED
#include <ivp_physics.hxx>
#include <ivp_cache_object.hxx>
#include <ivp_template_constraint.hxx>
#include <ivp_solver_core_reaction.hxx>
#ifndef WIN32
# pragma implementation "ivp_constraint_fixed_keyed.hxx"
#endif
#include <ivp_constraint_fixed_keyed.hxx>
IVP_Template_Constraint_Fixed_Keyframed::IVP_Template_Constraint_Fixed_Keyframed(){
}
IVP_Constraint_Fixed_Keyframed::~IVP_Constraint_Fixed_Keyframed(){
IVP_Controller_Manager::remove_controller_from_environment(this,IVP_TRUE); //delete silently
}
void IVP_Constraint_Fixed_Keyframed::core_is_going_to_be_deleted_event(IVP_Core *) {
P_DELETE_THIS(this);
}
IVP_DOUBLE IVP_Constraint_Fixed_Keyframed::get_minimum_simulation_frequency(){
return 1.0f;
}
void IVP_Constraint_Fixed_Keyframed::ensure_in_simulation(){
get_environment()->get_controller_manager()->ensure_controller_in_simulation(this);
}
/*
IVP_Template_Constraint &ivp_create_template_for_constraint_local(IVP_Real_Object *reference_object,
IVP_Real_Object *attached_object,
const IVP_Template_Constraint_Fixed_Keyframed *tin){
static IVP_Template_Constraint t;
t.set_fixed( reference_object, attached_object);
IVP_Cache_Object *co_attached = attached_object->get_cache_object_no_lock();
IVP_U_Point co_pos_ws( co_attached->m_world_f_object.get_position());
IVP_U_Point co_pos_Ros;
IVP_Cache_Object *co_reference = reference_object->get_cache_object_no_lock();
co_reference->transform_position_to_object_coords( & co_pos_ws, &co_pos_Ros);
t.set_fixing_point_Ros( &co_pos_Ros);
return t;
}
*/
//#define WATCHPOINT 0x56b56f0
//#define WATCHPOINT 0x381e810
IVP_Constraint_Fixed_Keyframed::IVP_Constraint_Fixed_Keyframed(IVP_Real_Object *reference_object, IVP_Real_Object *attached_object,
const IVP_Template_Constraint_Fixed_Keyframed *t)
//:IVP_Constraint_Local( ivp_create_template_for_constraint_local(reference_object,attached_object,t ))
{
if (!reference_object->get_core()->physical_unmoveable){
cores_of_constraint_system.add(reference_object->get_core());
}
if (!attached_object->get_core()->physical_unmoveable){
cores_of_constraint_system.add(attached_object->get_core());
}
reference_obj = reference_object;
attached_obj = attached_object;
max_translation_force.set( &t->max_translation_force);
max_torque.set(t->max_torque, t->max_torque, t->max_torque);
force_factor = t->force_factor;
damp_factor = t->damp_factor;
torque_factor = t->torque_factor;
angular_damp_factor = t->angular_damp_factor;
l_environment = reference_object->get_environment();
time_of_prime_orientation_0 = 0.0;
velocity_Ros.set_to_zero();
IVP_U_Matrix m_Ros_f_Aos;
IVP_Cache_Object *co_attached = attached_object->get_cache_object();
IVP_Cache_Object *co_reference = reference_object->get_cache_object();
co_reference->m_world_f_object.mimult4(&co_attached->m_world_f_object, &m_Ros_f_Aos);
co_attached->remove_reference();
co_reference->remove_reference();
//if (int(this) == WATCHPOINT){
//IVP_DOUBLE x = velocity_Ros.quad_length();
prime_position_Ros.set( m_Ros_f_Aos.get_position());
prime_orientation_0.set_quaternion( &m_Ros_f_Aos );
angular_velocity_set = IVP_FALSE;
get_environment()->get_controller_manager()->announce_controller_to_environment(this);
}
void IVP_Constraint_Fixed_Keyframed::do_simulation_controller(IVP_Event_Sim *es,IVP_U_Vector<IVP_Core> *cores){
IVP_Time current_time = es->environment->get_current_time();
//if (int(this) == WATCHPOINT)
// IVP_DOUBLE x = current_time.get_time();
IVP_Cache_Object *co_Ref = reference_obj->get_cache_object();
IVP_Cache_Object *co_Att = attached_obj->get_cache_object();
const IVP_U_Matrix *m_Rws_f_Ros = &co_Ref->m_world_f_object;
const IVP_U_Matrix *m_Aws_f_Aos = &co_Att->m_world_f_object;
IVP_U_Float_Point x_rot_axis_world(1,0,0);
IVP_U_Float_Point y_rot_axis_world(0,1,0);
IVP_U_Float_Point z_rot_axis_world(0,0,1);
IVP_Core *core_A = (reference_obj->get_core()->physical_unmoveable)? NULL : reference_obj->get_core();
IVP_Core *core_B = (attached_obj->get_core()->physical_unmoveable)? NULL : attached_obj->get_core();
// orientation
{
IVP_FLOAT dt = current_time - time_of_prime_orientation_0;
IVP_U_Quat new_q_Ros_f_Rrs;
if (angular_velocity_set){
new_q_Ros_f_Rrs.set_interpolate_smoothly( &prime_orientation_0, &prime_orientation_1,
(dt + es->delta_time ) * i_delta_prime_orientation_time);
}else{
new_q_Ros_f_Rrs = prime_orientation_0;
}
IVP_U_Matrix3 m_Ros_f_Rrs; new_q_Ros_f_Rrs.set_matrix( &m_Ros_f_Rrs );
IVP_U_Matrix3 m_Rws_f_Rrs; m_Rws_f_Ros->mmult3( & m_Ros_f_Rrs, &m_Rws_f_Rrs );
IVP_U_Matrix3 m_Rws_f_Aws; m_Aws_f_Aos->mi2mult3( &m_Rws_f_Rrs, &m_Rws_f_Aws );
IVP_U_Quat q; q.set_quaternion(&m_Rws_f_Aws);
IVP_U_Float_Point drRA_rs(2.0f * IVP_Inline_Math::fast_asin(q.x),
2.0f * IVP_Inline_Math::fast_asin(q.y),
2.0f * IVP_Inline_Math::fast_asin(q.z));
if ( q.w > 0.0f){
drRA_rs.mult(-1.0f);
}
IVP_Solver_Core_Reaction tcb;
tcb.init_reaction_solver_rotation_ws(core_B, core_A, &x_rot_axis_world, &y_rot_axis_world, &z_rot_axis_world);
//// invert matrix
IVP_RETURN_TYPE r = tcb.invert_3x3_matrix();
if(r==IVP_FAULT){
printf("do_constraint_system: Couldn't invert rot matrix!\n");
co_Ref->remove_reference();
co_Att->remove_reference();
return;
}
IVP_U_Matrix3 &tpm = tcb.m_velocity_ds_f_impulse_ds;
IVP_U_Float_Point delta_angles;
delta_angles.set_multiple( &drRA_rs, es->i_delta_time * this->torque_factor);
delta_angles.add_multiple( &tcb.delta_velocity_ds, -this->angular_damp_factor );
IVP_U_Float_Point rot_impulse_ws;
tpm.vmult3( & delta_angles, &rot_impulse_ws);
tcb.exert_angular_impulse_dim3(core_B, core_A, rot_impulse_ws);
}
// position
{
IVP_FLOAT dt = current_time - time_of_prime_position;
IVP_U_Point new_target_position_Ros;
new_target_position_Ros.add_multiple( &prime_position_Ros, &velocity_Ros, dt + es->delta_time);
IVP_U_Point target_pos_Ws;
m_Rws_f_Ros->vmult4( & new_target_position_Ros, &target_pos_Ws );
IVP_U_Float_Point delta_position_ws; delta_position_ws.inline_subtract_and_mult(
&target_pos_Ws, m_Aws_f_Aos->get_position(), this->force_factor * es->i_delta_time);
delta_position_ws.add_multiple( &reference_obj->get_core()->speed, damp_factor );
delta_position_ws.add_multiple( &attached_obj->get_core()->speed, -damp_factor );
co_Ref->remove_reference();
co_Att->remove_reference();
IVP_Solver_Core_Reaction tcb;
tcb.init_reaction_solver_translation_ws(core_B, core_A, target_pos_Ws, &x_rot_axis_world, &y_rot_axis_world, &z_rot_axis_world);
//// invert matrix
IVP_RETURN_TYPE r = tcb.invert_3x3_matrix();
if(r==IVP_FAULT){
printf("do_constraint_system: Couldn't invert rot matrix!\n");
return;
}
IVP_U_Matrix3 &tpm = tcb.m_velocity_ds_f_impulse_ds;
IVP_U_Float_Point impulse_ws; tpm.vmult3( & delta_position_ws, &impulse_ws);
tcb.exert_impulse_dim3(core_B, core_A, impulse_ws);
}
}
void IVP_Constraint_Fixed_Keyframed::set_prime_position_Ros(const IVP_U_Point * position,const IVP_U_Float_Point * velocity ,const IVP_Time & time ){
time_of_prime_position = time;
prime_position_Ros.set(position);
velocity_Ros.set(velocity);
// if (int(this) == WATCHPOINT)
// IVP_DOUBLE x = velocity->quad_length();
this->ensure_in_simulation();
}
void IVP_Constraint_Fixed_Keyframed::set_prime_orientation_Ros( const IVP_U_Quat * orientation0,const IVP_Time & time0, const IVP_U_Quat * orientation1,const IVP_FLOAT dt ){
prime_orientation_0 = *orientation0;
if ( orientation1 ){
prime_orientation_1 = *orientation1;
i_delta_prime_orientation_time = 1.0f / (dt);
angular_velocity_set = IVP_TRUE;
}else{
angular_velocity_set = IVP_FALSE;
}
time_of_prime_orientation_0 = time0;
this->ensure_in_simulation();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -