📄 ivp_object.cxx
字号:
};
IVP_Cluster::~IVP_Cluster(){ // silently deletes a cluster
while(objects){
delete objects;
// objects->delete_silently();
}
}
void IVP_Cluster::add_object(IVP_Object *object){
object->next_in_cluster = objects;
object->prev_in_cluster = NULL;
if (objects != NULL){
objects->prev_in_cluster = object;
}
objects = object;
object->father_cluster = this;
};
void IVP_Cluster::remove_object(IVP_Object *object){
if ( object->prev_in_cluster == NULL){
objects = object->next_in_cluster;
}else{
object->prev_in_cluster->next_in_cluster = object->next_in_cluster;
}
if ( object->next_in_cluster != NULL){
object->next_in_cluster->prev_in_cluster = object->prev_in_cluster;
}
};
void IVP_Real_Object::calc_at_matrix(IVP_Time current_time,IVP_U_Matrix *m_world_f_object_out ) const
{
IVP_U_Quat q_world_f_object;
IVP_Core *core = get_core();
core->inline_calc_at_quaternion(current_time, &q_world_f_object);
core->inline_calc_at_position(current_time, &m_world_f_object_out->vv);
q_world_f_object.set_matrix( m_world_f_object_out );
if (!flags.shift_core_f_object_is_zero){
m_world_f_object_out->vmult4( &this->shift_core_f_object , &m_world_f_object_out->vv);
}
if ( this->q_core_f_object){
q_world_f_object.inline_set_mult_quat( &q_world_f_object, this->q_core_f_object );
q_world_f_object.set_matrix( m_world_f_object_out );
}
}
void IVP_Real_Object::calc_at_quaternion(IVP_Time current_time,
IVP_U_Quat *q_world_f_object_out,
IVP_U_Point *position_out) const
{
IVP_Core *core = this->get_core();
core->inline_calc_at_quaternion(current_time, q_world_f_object_out);
core->inline_calc_at_position(current_time, position_out);
if (!flags.shift_core_f_object_is_zero){
IVP_U_Matrix m_world_f_object;
q_world_f_object_out->set_matrix( &m_world_f_object );
m_world_f_object.vv.set(position_out);
m_world_f_object.vmult4( &this->shift_core_f_object , position_out);
}
if ( this->q_core_f_object){
q_world_f_object_out->inline_set_mult_quat( q_world_f_object_out, this->q_core_f_object );
}
}
void IVP_Real_Object::init_object_core(IVP_Environment *i_environment, const IVP_Template_Real_Object *templ){
// used for instances
IVP_U_Float_Point center;
IVP_U_Quat mass_axis;
IVP_U_Matrix m_object_f_core;
mass_axis.init();
IVP_OBJECT_TYPE type = get_type();
if (templ->mass_center_override){
center.set(templ->mass_center_override->get_position());
}else{
surface_manager->get_mass_center(¢er);
}
mass_axis.set_matrix(&m_object_f_core);
m_object_f_core.vv.set(¢er);
set_new_m_object_f_core( &m_object_f_core );
IVP_Core *core = get_core();
// radius
IVP_FLOAT rad, rad_dev;
switch (type){
case IVP_POLYGON:
surface_manager->get_radius_and_radius_dev_to_given_center(¢er, &rad, &rad_dev);
break;
case IVP_BALL:
rad = 0.0f;
rad_dev = 0.0f;
break;
default:
CORE;
}
rad += this->get_extra_radius();
core->set_radius(rad,rad_dev);
IVP_DOUBLE mass = templ->mass;
if (templ->mass < P_RES_EPS){
mass = 1.0f;
}
// mass
IVP_U_Float_Hesse &rot_inertia = (IVP_U_Float_Hesse &)* core->get_rot_inertia();
if (templ->rot_inertia_is_factor){
IVP_U_Float_Point rot_in;
switch (type){
case IVP_POLYGON:
surface_manager->get_rotation_inertia( &rot_in );
break;
case IVP_BALL:{
IVP_DOUBLE rot = (2.0f/5.0f)* rad * rad;
rot_in.set(rot,rot,rot);
break;
}
default:
CORE;
}
rot_inertia.set_pairwise_mult( &rot_in, &templ->rot_inertia);
rot_inertia.mult(mass);
}else{
rot_inertia.set(&templ->rot_inertia);
}
if( templ->auto_check_rot_inertia != 0.0f ) {
IVP_FLOAT min_inertia_value = rot_inertia.real_length() * templ->auto_check_rot_inertia;
int hh;
for(hh=0;hh<3;hh++) {
if(rot_inertia.k[hh]<min_inertia_value) {
rot_inertia.k[hh]=min_inertia_value;
}
}
}
rot_inertia.hesse_val = mass;
// speed damps
core->speed_damp_factor = (IVP_FLOAT)templ->speed_damp_factor;
core->rot_speed_damp_factor.set( &templ->rot_speed_damp_factor);
IVP_U_Matrix m_core_f_object;
m_core_f_object.set_transpose(&m_object_f_core);
core->rot_speed.set_to_zero();
core->speed.set_to_zero();
core->calc_calc();
core->transform_PSI_matrizes_core(&m_object_f_core);
IVP_Event_Sim es( i_environment, i_environment->get_next_PSI_time() - i_environment->get_current_time());
core->calc_next_PSI_matrix_zero_speed( &es );
}
int IVP_Real_Object::get_collision_check_reference_count(){ // see IVP_Universe_Manager for details
IVP_OV_Element *ov = get_ov_element();
if (!ov) return -1; // reference count for non colliding objects
return ov->collision_fvector.len();
}
void IVP_Real_Object::get_geom_center_world_space(IVP_U_Point *geom_center_out) const{
const IVP_U_Matrix *m_world_f_core = get_core()->get_m_world_f_core_PSI();
geom_center_out->set(&m_world_f_core->vv);
}
IVP_FLOAT IVP_Real_Object::get_geom_radius() const{
return get_core()->upper_limit_radius;
}
IVP_FLOAT IVP_Real_Object::get_geom_center_speed()const{
return get_core()->speed.real_length();
}
void IVP_Real_Object::get_geom_center_speed_vec(IVP_U_Point *speed_ws_out) const {
speed_ws_out->set(&get_core()->speed);
}
IVP_Controller_VHash::~IVP_Controller_VHash()
{
#if 0 /*TL */
for (int i=this->len()-1; i>=0; i--) {
IVP_Controller *controller;
controller = (IVP_Controller *)this->element_at(i);
if (controller){
controller->object_is_going_to_be_deleted_event(real_object);
}
}
#endif
}
int IVP_Controller_VHash::controller_to_index(IVP_Controller *controller)
{
return hash_index( (char *)&controller, sizeof(controller) );
}
IVP_BOOL IVP_Controller_VHash::compare(void *elem0, void *elem1) const
{
if ( elem0 !=elem1 ) return(IVP_FALSE);
return(IVP_TRUE);
}
void IVP_Real_Object::do_radar_checking(IVP_Radar *radar){
// loop through all synapses
IVP_Radar_Hit hit;
IVP_DOUBLE max_range = radar->max_range;
{
IVP_Synapse_Real *syn;
// check real synapse
for (syn = exact_synapses; syn; syn = syn->get_next()){
IVP_Mindist *md = syn->get_mindist();
int THIS = 0;
if ( md->get_synapse(1)->get_object() == this ) THIS = 1;
IVP_Synapse_Real *syn0 = md->get_synapse(THIS);
IVP_Synapse_Real *syn1 = md->get_synapse(1-THIS);
hit.this_object = syn0->get_object();
hit.other_object = syn1->get_object();
IVP_DOUBLE dist = md->get_length();
if (dist <= max_range){
hit.dist = dist;
radar->radar_hit(&hit);
}
}
}
// check hulls
IVP_Hull_Manager *hm = get_hull_manager();
IVP_U_Min_List *ss = hm->get_sorted_synapses();
max_range = radar->max_range + hm->get_current_hull_time();
IVP_U_Min_List_Enumerator mindists(ss);
IVP_Listener_Hull *supers;
while ( (supers = (IVP_Listener_Hull*)mindists.get_next_element_lt(max_range))!= NULL ){
if (supers->get_type() != IVP_HULL_ELEM_POLYGON) continue;
IVP_Synapse_Real *syn = (IVP_Synapse_Real*)supers;
IVP_Mindist *md = syn->get_mindist();
md->recalc_mindist(); // @@@@ lots of cpu cycles wasted here !!!
if (md->recalc_result != IVP_MDRR_OK) continue;
int is_this = 0;
if ( md->get_synapse(1)->get_object() == this ) is_this = 1;
IVP_Synapse_Real *syn0 = md->get_synapse(is_this);
IVP_Synapse_Real *syn1 = md->get_synapse(1-is_this);
hit.this_object = syn0->get_object();
hit.other_object = syn1->get_object();
IVP_DOUBLE dist = md->get_length();
if (dist <= max_range){
hit.dist = dist;
radar->radar_hit(&hit);
}
}
// check spheres
}
void IVP_Real_Object::convert_to_phantom(const IVP_Template_Phantom *tmpl)
{
P_DELETE(controller_phantom);
controller_phantom = new IVP_Controller_Phantom(this,tmpl);
}
void IVP_Real_Object::beam_object_to_new_position( const IVP_U_Quat *rotation_world_f_object, const IVP_U_Point *position_w_f_o, IVP_BOOL optimize_for_repeated_calls)
{
IVP_Core *core = this->get_core();
IVP_U_Quat rotation_world_f_core(*rotation_world_f_object);
IVP_U_Point position_w_f_c(*position_w_f_o);
if (!flags.shift_core_f_object_is_zero)
{
IVP_U_Matrix m_world_f_object;
rotation_world_f_object->set_matrix( &m_world_f_object );
m_world_f_object.get_position()->set(position_w_f_o);
IVP_U_Float_Point inv_shift_core_f_object;
inv_shift_core_f_object.set_negative(&shift_core_f_object);
m_world_f_object.vmult4( &inv_shift_core_f_object , &position_w_f_c);
}
if ( this->q_core_f_object)
{
rotation_world_f_core.set_div_unit_quat( rotation_world_f_object, this->q_core_f_object );
}
IVP_Calc_Next_PSI_Solver nps(core);
nps.set_transformation(&rotation_world_f_core, &position_w_f_c, optimize_for_repeated_calls);
}
void IVP_Real_Object::async_add_speed_object_ws( const IVP_U_Float_Point *speed_vec )
{
this->ensure_in_simulation();
this->physical_core->speed_change.add(speed_vec);
//this->physical_core->environment->add_delayed_push_core(this->physical_core);
}
void IVP_Real_Object::async_add_rot_speed_object_cs( const IVP_U_Float_Point *rotation_vec )
{
this->ensure_in_simulation();
IVP_Core *core = this->get_core();
core->rot_speed_change.add(rotation_vec);
//core->environment->add_delayed_push_core(core);
}
void IVP_Real_Object::async_push_object_ws( const IVP_U_Point *position_ws_, const IVP_U_Float_Point *impulse_ws_)
{
this->ensure_in_simulation();
IVP_Core *core = this->get_core();
IVP_U_Matrix m_world_f_core;
core->calc_at_matrix( get_environment()->get_current_time(), & m_world_f_core);
IVP_U_Float_Point impulse_cs;
IVP_U_Float_Point position_cs;
m_world_f_core.vimult4( position_ws_, &position_cs);
m_world_f_core.vimult3( impulse_ws_, &impulse_cs);
core->async_push_core(&position_cs, &impulse_cs, impulse_ws_);
}
void IVP_Real_Object::ensure_in_simulation(){
// Note IVP_MT_STATIC != IVP_MT_NOT_SIM
if (this->get_movement_state()!=IVP_MT_NOT_SIM){
this->get_core()->reset_freeze_check_values();
}else{
//printf("add_reviving\n");
IVP_ASSERT( !this->get_core()->physical_unmoveable );
environment->add_revive_core(this->friction_core);
}
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -