📄 ivp_object.cxx
字号:
physical_core = new IVP_Core(this, q_world_f_object, position, templ_obj->physical_unmoveable ,templ_obj->enable_piling_optimization);
this->friction_core=physical_core;
this->original_core=physical_core;
if (templ_obj->physical_unmoveable){
this->set_movement_state(IVP_MT_STATIC);
}else{
this->set_movement_state(IVP_MT_NOT_SIM);
}
this->l_default_material = templ_obj->material;
// IVP_ASSERT(l_default_material);
physical_core->environment->get_cluster_manager()->add_object(this);
this->client_data = templ_obj->client_data;
}
void IVP_Real_Object::set_new_surface_manager( IVP_SurfaceManager *new_sm){
IVP_BOOL c_enabled = is_collision_detection_enabled();
this->enable_collision_detection(IVP_FALSE);
this->surface_manager = new_sm;
IVP_FLOAT rad, rad_dev;
IVP_OBJECT_TYPE type = get_type();
switch (type){
case IVP_POLYGON:
{
IVP_U_Float_Point center;
center.set_negative( &this->shift_core_f_object);
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();
if ( rad > get_core()->upper_limit_radius){
get_core()->upper_limit_radius = rad;
}
if ( rad_dev > get_core()->max_surface_deviation){
get_core()->max_surface_deviation = rad_dev;
}
this->enable_collision_detection( c_enabled);
}
void IVP_Real_Object::recalc_core_radius( ){
IVP_FLOAT rad, rad_dev;
IVP_OBJECT_TYPE type = get_type();
switch (type){
case IVP_POLYGON:
{
IVP_U_Float_Point center;
center.set_negative( &this->shift_core_f_object);
surface_manager->get_radius_and_radius_dev_to_given_center(¢er, &rad, &rad_dev);
}
break;
case IVP_BALL:
rad = rad_dev = this->shift_core_f_object.real_length();
break;
default:
CORE;
}
rad += this->get_extra_radius();
if ( rad > get_core()->upper_limit_radius){
get_core()->upper_limit_radius = rad;
}
if ( rad_dev > get_core()->max_surface_deviation){
get_core()->max_surface_deviation = rad_dev;
}
}
void IVP_Real_Object::set_extra_radius( IVP_DOUBLE new_radius ){
if ( new_radius > this->extra_radius){
this->extra_radius = new_radius;
this->recalc_core_radius();
}else{
this->extra_radius = new_radius;
this->get_core()->upper_limit_radius = 0.0f;
this->get_core()->max_surface_deviation = 0.0f;
for ( int i = this->get_core()->objects.len()-1;i>=0; i--){
IVP_Real_Object *o = this->get_core()->objects.element_at(i);
o->recalc_core_radius();
}
}
}
IVP_Real_Object::~IVP_Real_Object()
{
P_DELETE(controller_phantom);
get_hull_manager()->delete_hull_manager(); // remove all internal
clear_internal_references(); // anchors and mindists
{ // fire global 'object deleted' event
IVP_Event_Object event_deleted;
event_deleted.real_object = this;
event_deleted.environment = environment;
environment->fire_event_object_deleted(&event_deleted);
}
if (this->flags.collision_listener_exists){ // local friction listener
environment->get_cluster_manager()->fire_event_collision_object_deleted(this);
}
if (this->flags.object_listener_exists){ // fire object-dependant 'object deleted' event
IVP_Event_Object event_deleted;
event_deleted.real_object = this;
event_deleted.environment = environment;
environment->get_cluster_manager()->fire_event_object_deleted(&event_deleted);
}
physical_core->environment->get_cluster_manager()->remove_object(this);
// from this point, only internal (callback free) memory frees
if (cache_object){
get_environment()->get_cache_object_manager()->invalid_cache_object(this);
}
physical_core->unlink_obj_from_core_and_maybe_destroy(this);
if(original_core!=physical_core) {
original_core->unlink_obj_from_core_and_maybe_destroy(this);
}
if((friction_core!=original_core) && (friction_core!=physical_core)) {
friction_core->unlink_obj_from_core_and_maybe_destroy(this);
}
P_DELETE(q_core_f_object);
}
void IVP_Real_Object::reset_time( IVP_Time offset){
get_hull_manager()->reset_time(offset);
}
/**************************************************************************************
* Name: delete_and_check_vicinity
* Description: deletes object and revives surroundings
**************************************************************************************/
void IVP_Real_Object::delete_and_check_vicinity(){
if (!this) return;
IVP_Core *my_core=this->get_core();
if(!my_core->physical_unmoveable) {
my_core->sim_unit_of_core->sim_unit_ensure_in_simulation();
}
revive_nearest_objects_grow_fs();
IVP_Real_Object *tmp_o=this;
P_DELETE(tmp_o);
}
/**************************************************************************************
* Name: delete_silently
* Description: Silently deletes object, vicinity will stay frozen
**************************************************************************************/
void IVP_Real_Object::delete_silently(){
IVP_Real_Object *tmp_o=this;
P_DELETE(tmp_o);
}
void IVP_Real_Object::recalc_invalid_mindists_of_object() {
IVP_Synapse_Real *first_syn,*next_syn;
for ( first_syn = invalid_synapses; first_syn; first_syn = next_syn){
next_syn=first_syn->get_next();
IVP_Mindist *mdist = first_syn->get_mindist();
IVP_ASSERT (mdist->mindist_function == IVP_MF_COLLISION);
mdist->recalc_invalid_mindist();
if (mdist->recalc_result == IVP_MDRR_INTRUSION){
continue;
}
IVP_Mindist_Manager *mm = environment->get_mindist_manager();
mm->remove_invalid_mindist(mdist);
mm->insert_exact_mindist(mdist);
if (mdist->get_length() < 0){
continue;
}
}
}
void IVP_Real_Object::recalc_exact_mindists_of_object() {
IVP_Synapse_Real *first_syn,*next_syn;
IVP_Mindist_Manager *mm = environment->get_mindist_manager();
for ( first_syn=exact_synapses; first_syn; first_syn = next_syn){
next_syn=first_syn->get_next();
IVP_Mindist *mdist = first_syn->get_mindist();
mm->recalc_exact_mindist( mdist );
}
}
void IVP_Real_Object::get_all_near_mindists() {
IVP_Movement_Type temp_movement= (IVP_Movement_Type)physical_core->movement_state;
physical_core->movement_state=IVP_MT_GET_MINDIST;
physical_core->environment->get_mindist_manager()->recheck_ov_element(this);
this->physical_core->movement_state=temp_movement;
}
void IVP_Real_Object::recheck_collision_filter(){
if (this->ov_element){
physical_core->environment->get_mindist_manager()->recheck_ov_element(this);
}
}
void IVP_Real_Object::revive_nearest_objects_grow_fs() {
if(this->get_core()->physical_unmoveable) {
this->get_all_near_mindists();
this->get_core()->grow_friction_system();
this->get_core()->revive_adjacent_to_unmoveable();
} else {
this->get_core()->ensure_core_to_be_in_simulation();
}
}
void IVP_Real_Object::unlink_contact_points(IVP_BOOL silent) {
// then delete static friction datas @@@OS, loop only once + flag
int debug_once=0;
IVP_Synapse_Friction *fr_synapse;
while((fr_synapse=this->get_first_friction_synapse())!=NULL) {
IVP_Contact_Point *fr_mindist=fr_synapse->get_contact_point();
IVP_Friction_System *fr_sys=fr_mindist->l_friction_system;
IVP_IF(debug_once) {
debug_once=1;
IVP_Synapse_Friction *debug_syn=this->get_first_friction_synapse();
printf("still_left_fd ");
while(debug_syn) {
printf("fd %lx sys %lx ",(long)debug_syn->get_contact_point(),
(long)debug_syn->get_contact_point()->l_friction_system);
debug_syn=debug_syn->get_next();
}
printf("\n");
fr_sys->debug_fs_out_ascii();
printf("newl\n");
}
IVP_Core *core0,*core1;
core0=fr_mindist->get_synapse(0)->l_obj->friction_core;
core1=fr_mindist->get_synapse(1)->l_obj->friction_core;
if(!silent) {
core0->ensure_core_to_be_in_simulation();
core1->ensure_core_to_be_in_simulation();
}
fr_sys->delete_friction_distance(fr_mindist);
if(fr_sys->friction_dist_number==0) {
P_DELETE(fr_sys);
}
}
}
void IVP_Real_Object::clear_internal_references() {
// first clear actuators
IVP_Anchor *my_anchor;
IVP_Anchor *last_anchor = 0;
while( (my_anchor=this->get_first_anchor()) != NULL) {
my_anchor->object_is_going_to_be_deleted_event(this);
if (my_anchor == last_anchor){ // check for errors in anchors
CORE;
}
last_anchor = my_anchor;
}
unlink_contact_points(IVP_TRUE); //do it silently (do not wake up objects)
IVP_Synapse_Real *fr_synapse;
while((fr_synapse=this->get_first_exact_synapse())!=NULL) {
IVP_Mindist *my_mindist=fr_synapse->get_mindist();
P_DELETE(my_mindist);
}
}
IVP_Object::IVP_Object(IVP_Cluster *father, const IVP_Template_Object *templ){
this->init(father->environment);
father->add_object(this);
this->name = p_strdup(templ->get_name());
}
IVP_Object::IVP_Object(IVP_Environment *env){
this->init(env);
}
void IVP_Object::init(IVP_Environment *env){
next_in_cluster = prev_in_cluster = father_cluster = NULL;
environment = env;
name=0;
this->set_type(IVP_NONE);
}
IVP_Object::~IVP_Object(){
if (father_cluster){
this->father_cluster->remove_object(this);
}
P_FREE(this->name);
IVP_ASSERT(environment);
environment = NULL;
}
void IVP_Real_Object::calc_m_core_f_object( IVP_U_Matrix *m_core_f_object )
{
m_core_f_object->init();
if ( q_core_f_object )
{
q_core_f_object->set_matrix( m_core_f_object );
}
else
{
m_core_f_object->init();
}
m_core_f_object->vv.set( &shift_core_f_object );
}
void IVP_Real_Object::get_m_world_f_object_AT (IVP_U_Matrix *m_world_f_object_out) const
{ calc_at_matrix(get_environment()->get_current_time(), m_world_f_object_out); };
void IVP_Real_Object::get_quat_world_f_object_AT(IVP_U_Quat *quat_world_f_object, IVP_U_Point *position) const // ditto (using quaternions)
{ calc_at_quaternion(get_environment()->get_current_time(), quat_world_f_object, position); }
IVP_Cluster::IVP_Cluster(IVP_Cluster *father, IVP_Template_Cluster *templ): IVP_Object(father, templ) {
objects = NULL;
this->set_type(IVP_CLUSTER);
};
IVP_Cluster::IVP_Cluster(IVP_Environment *env): IVP_Object(env){
objects = NULL;
this->set_type(IVP_CLUSTER);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -