⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ivp_object.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 3 页
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.


#ifndef WIN32
#	pragma implementation "ivp_object.hxx"
#	pragma implementation "ivp_real_object.hxx"
#endif
 
#include <ivp_physics.hxx>
#include <string.h>

#include <ivu_matrix_macros.hxx>
#include <ivu_float.hxx>
#include <ivp_core_macros.hxx>
#include <ivp_sim_unit.hxx>
#include <ivp_physic_private.hxx>

#include <ivp_listener_object.hxx>
#include <ivp_templates.hxx>
#include <ivp_hull_manager.hxx>
#include <ivp_mindist_intern.hxx>
#include <ivp_friction.hxx>
#include <ivp_actuator.hxx>
#include <ivp_cache_object.hxx>
#include <ivp_debug_manager.hxx>
#include <ivp_i_friction_hash.hxx>
#include <ivp_i_controller_vhash.hxx>
#include <ivp_clustering_longrange.hxx>
#include <ivu_min_hash.hxx>
#include <ivp_radar.hxx>
#include <ivp_phantom.hxx>
#include <ivp_calc_next_psi_solver.hxx>


void IVP_Real_Object::change_nocoll_group_ident(const char *new_string ) {
    if (!new_string){
	nocoll_group_ident[0] = 0;
	return;
    }
    if (strlen(new_string) > IVP_NO_COLL_GROUP_STRING_LEN){
	CORE;
    }
    strncpy( nocoll_group_ident, new_string, IVP_NO_COLL_GROUP_STRING_LEN);
}

void IVP_Real_Object::set_pinned(IVP_BOOL is_pinned)
{
    IVP_Core* core = this->get_core();

    /**
     * Set the core pinned flag and zero the velocities
     */
    core->pinned = is_pinned;
    core->speed.set_to_zero();
    core->rot_speed.set_to_zero();

    if(is_pinned == IVP_TRUE)
    {
	/**
	 * Disable collision detection
	 */
	IVP_BOOL c_enabled = is_collision_detection_enabled();
	this->enable_collision_detection(IVP_FALSE);

	/**
	 * Pinning: Set the inertia tensor inverse and mass inverse to 0; this
	 * will make the object virtually of infinite mass (i.e. 1/mass ~= 0)
	 */
	core->inv_rot_inertia.set(0.0f, 0.0f, 0.0f);
	core->inv_rot_inertia.hesse_val = 0.0f;

	/**
	 * Reset collision detection
	 */
	this->enable_collision_detection(c_enabled);
    }
    else
    {
	/**
	 * Unpinning: Set the inertia tensor inverse to be the inverse of the
	 * inertia tensor, and the mass inverse to be the inverse of the mass.
	 * (i.e., restore the object mass values)
	 */
	const IVP_U_Float_Point* i = core->get_rot_inertia();
	core->inv_rot_inertia.set(1.0f / i->k[0], 1.0f / i->k[1], 1.0f / i->k[2]);
	core->inv_rot_inertia.hesse_val = 1.0f / core->get_mass();

        /**
	 * Rebuild mindists for this object
	 */
	this->get_environment()->get_mindist_manager()->recheck_ov_element(this);
    }
}

void IVP_Real_Object::change_fast_piling_allowed(IVP_BOOL bool_flag) {
    this->friction_core->set_fast_piling_allowed(bool_flag);
}

void IVP_Real_Object::change_mass( IVP_FLOAT new_mass ) {
    this->get_core()->set_mass(new_mass);
}

void IVP_Real_Object::change_unmovable_flag( IVP_BOOL flag ) {
    //printf("changing_unmov_flag to %d at time %f  csimfl %d  osimfl %d\n",flag,get_core()->environment->get_current_time(),this->get_core()->movement_state,this->object_movement_state);
    
    //friction info is stored differently in movables and unmovables, so destroy first
    IVP_Core *my_core=this->get_core();
    if( my_core->physical_unmoveable == flag ) {
	return;
    }
    int d;
    for(d = my_core->objects.len()-1;d>=0;d--) {
	IVP_Real_Object *r_obj=my_core->objects.element_at(d);
	r_obj->unlink_contact_points(IVP_FALSE);
    }
    //printf("for_umove_info %lx\n",(long)my_core->core_friction_info.for_unmoveables.l_friction_info_hash);
    if(my_core->physical_unmoveable) {
	P_DELETE(my_core->core_friction_info.for_unmoveables.l_friction_info_hash);
    } else {
	my_core->core_friction_info.for_moveables.moveable_core_friction_info=NULL;
    }
    if(my_core->movement_state < IVP_MT_NOT_SIM) {
        my_core->freeze_simulation_core();
    }
    
    my_core->physical_unmoveable = flag;
    if(flag==IVP_TRUE) {
	//switched from movable to unmovable
	//printf("switch_to_unmovable: controllers: %d\n",my_core->controllers_of_core.len());
	if(my_core->sim_unit_of_core) {
	    my_core->sim_unit_of_core->sim_unit_remove_core(my_core);
	    my_core->sim_unit_of_core=new IVP_Simulation_Unit();
	    my_core->sim_unit_of_core->add_sim_unit_core(my_core);
	    my_core->sim_unit_of_core->set_unit_movement_type(IVP_MT_NOT_SIM);
	    
	    //clear all controllers. CORRECT would be: give all controllers signal that core switched to unmovable
	    int ic;
	    for(ic=my_core->controllers_of_core.len()-1;ic>=0;ic--) {
		my_core->controllers_of_core.remove_at(ic);
	    }
	    
	    my_core->environment->get_sim_units_manager()->add_sim_unit_to_manager(my_core->sim_unit_of_core);
	    my_core->add_core_controller(my_core->environment->standard_gravity_controller);
	}	
    } else {
	//printf("switch_to_movable\n");
    }
}

void IVP_Real_Object::recompile_values_changed() {
    this->get_core()->values_changed_recalc_redundants();
}

void IVP_Real_Object::recompile_material_changed() {
    this->get_core()->values_changed_recalc_redundants();
}

void IVP_Real_Object::enable_collision_detection(IVP_BOOL enable){
    if (enable){
	if (!this->flags.collision_detection_enabled ){
	    get_environment()->get_mindist_manager()->enable_collision_detection_for_object(this);
	    this->flags.collision_detection_enabled = IVP_TRUE;
	}
    }else{
	if (this->flags.collision_detection_enabled ){
	    P_DELETE(this->ov_element);
	    this->flags.collision_detection_enabled = IVP_FALSE;
	    unlink_contact_points(IVP_TRUE); //do it silently (do not wake up objects)
	}
    }
}


void IVP_Real_Object::ensure_in_simulation_now(){
    // Note IVP_MT_STATIC != IVP_MT_NOT_SIM
    IVP_ASSERT( !this->get_core()->physical_unmoveable );
    if (this->physical_core->movement_state==IVP_MT_NOT_SIM){
	this->revive_object_for_simulation();
    }
};



void IVP_Real_Object::set_new_m_object_f_core( const IVP_U_Matrix *new_m_object_f_core){

    IVP_U_Matrix new_m_core_f_object; new_m_core_f_object.set_transpose(new_m_object_f_core);
    IVP_Anchor *a;
    for (a = anchors; a ; a= a->anchor_next_in_object){
	new_m_core_f_object.vmult4( &a->object_pos, &a->core_pos );
    }
    if ( new_m_core_f_object.vv.quad_length() < P_RES_EPS * P_RES_EPS){
	flags.shift_core_f_object_is_zero = IVP_TRUE;
	shift_core_f_object.set_to_zero();
    }else{
	shift_core_f_object.set( &new_m_core_f_object.vv );
	flags.shift_core_f_object_is_zero = IVP_FALSE;
    }
    const IVP_U_Matrix *m = new_m_object_f_core;
    if ( m->get_elem(0,0) == 1.0f && m->get_elem(1,1) == 1.0f && m->get_elem(2,2) == 1.0f ){
	P_DELETE( q_core_f_object );
    }else{
	if (!q_core_f_object) q_core_f_object = new IVP_U_Quat();
	q_core_f_object->set_quaternion(&new_m_core_f_object);
	q_core_f_object->normize_quat();
    }
    // invalid caches !!
    if (cache_object){
	get_environment()->get_cache_object_manager()->invalid_cache_object(this);			// removes cache_ledge_point too
    }

}


void IVP_Real_Object::set_new_quat_object_f_core( const IVP_U_Quat *new_quat_object_f_core, const IVP_U_Point *trans_object_f_core){
    IVP_U_Matrix m;
    new_quat_object_f_core->set_matrix(&m);
    m.vv.set(trans_object_f_core);
    set_new_m_object_f_core(&m);
}



void IVP_Real_Object::add_listener_collision(IVP_Listener_Collision *listener){
    environment->get_cluster_manager()->add_listener_collision(this,listener);
}

void IVP_Real_Object::remove_listener_collision(IVP_Listener_Collision *listener){
    environment->get_cluster_manager()->remove_listener_collision(this,listener);
}

void IVP_Real_Object::add_listener_object(IVP_Listener_Object *listener){
    environment->get_cluster_manager()->add_listener_object(this,listener);
}

void IVP_Real_Object::remove_listener_object(IVP_Listener_Object *listener){
    environment->get_cluster_manager()->remove_listener_object(this,listener);
}


void IVP_Real_Object::insert_anchor(IVP_Anchor *new_anchor)
{
    new_anchor->anchor_prev_in_object=NULL;
    new_anchor->anchor_next_in_object=this->anchors;
    if (this->anchors){
	this->anchors->anchor_prev_in_object=new_anchor;
    }
    this->anchors=new_anchor;
}

void IVP_Real_Object::remove_anchor(IVP_Anchor *destroy_anch)
{
    IVP_Anchor *previous=destroy_anch->anchor_prev_in_object;
    IVP_Anchor *following=destroy_anch->anchor_next_in_object;
    if(previous!=NULL)
    {
	previous->anchor_next_in_object=following;
    } else {
	this->anchors=following;
    }

    if(following!=NULL)
    {
	following->anchor_prev_in_object=previous;
    }
}

// update all mindists between this objects and other objects whose core has invalid 'mindist_event_already_done'
void IVP_Real_Object::update_exact_mindist_events_of_object() {
    IVP_Synapse_Real *syn, *syn_next;	// minimal dist may remove itself from list
    for (syn = this->get_first_exact_synapse(); syn; syn = syn_next){
	syn_next= syn->get_next();
	IVP_Mindist *mindist = syn->get_mindist();    
	IVP_Core *core0 = mindist->get_synapse(0)->get_object()->physical_core;
	IVP_Core *core1 = mindist->get_synapse(1)->get_object()->physical_core;
	//at least one core has already right time code
	if(core0->mindist_event_already_done != core1->mindist_event_already_done) {	  /// #+# OS: vector for recalc mindists
	  mindist->recalc_mindist();			// should not be needed as the current position has not changed
	  if (mindist->recalc_result == IVP_MDRR_OK){ 
	    mindist->update_exact_mindist_events(IVP_FALSE, IVP_EH_BIG_DELAY);	// check length, do not check for hull, update time manager ...
	  }
	}
    }    
}

IVP_BOOL IVP_Real_Object::disable_simulation() {    
    IVP_Core *core=get_core();
    if(core->physical_unmoveable) {
        return IVP_TRUE;
    }
    if(core->is_in_wakeup_vec) {
        core->environment->remove_revive_core(core);
    }
    
    if(core->movement_state < IVP_MT_NOT_SIM) {
           for(int c = core->objects.len()-1;c>=0;c--) {
	       IVP_Real_Object *r_obj=core->objects.element_at(c);

	       r_obj->unlink_contact_points(IVP_TRUE); //trick to prevent any friction systems to wake up my object again
           }           
	   
	   core->q_world_f_core_calm_reference[0].set(&core->q_world_f_core_next_psi);
           core->position_world_f_core_calm_reference[0].set( &core->pos_world_f_core_last_psi );
	   IVP_Time now_time=core->environment->get_current_time();
	   IVP_Time ref_time=now_time-20; //bad hack: this ensures that 'sim_unit_calc_movement_state' switches off simulation
           core->time_of_calm_reference[0] = ref_time;

	   core->sim_unit_of_core->do_sim_unit_union_find();

	   return core->sim_unit_of_core->sim_unit_calc_movement_state(core->environment);
    }
    return IVP_TRUE;
}

// called at AT-Time
// normally wake up at PSI-time not allowed (not allowed in simulate_sim_units loop)
void IVP_Real_Object::revive_object_for_simulation()
{
    if(this->get_movement_state() == IVP_MT_NOT_SIM){	// STATICS won't be revived too
        //IVP_Environment *env=this->get_environment();
	//IVP_ASSERT( env->state == IVP_ES_AT ); //TL: without this assert no controll
//	this->friction_core->init_core_for_simulation();

	this->friction_core->sim_unit_of_core->sim_unit_revive_for_simulation(this->friction_core->environment);
    }
    
}


IVP_Real_Object::IVP_Real_Object(IVP_Cluster *cluster,IVP_SurfaceManager *surface_manager_,
			       const IVP_Template_Real_Object *templ_obj, const IVP_U_Quat *q_world_f_object, const IVP_U_Point *position)
    : IVP_Real_Object_Fast(cluster, templ_obj)
{
    IVP_U_Quat q_world_f_object_static;
    if (!q_world_f_object){
	q_world_f_object = &q_world_f_object_static;
	q_world_f_object_static.init();
    }
//	ivp_message("IVP_Real_Object::IVP_Real_Object 0x%x - %s\n", this, templ_obj->get_name());
    
    exact_synapses = NULL;
    invalid_synapses = NULL;
    friction_synapses = NULL;
    surface_manager = surface_manager_;
    anchors = NULL;
    ov_element = NULL;			// will be set by IVP_Mindist_Manager::enable_collision_detection
    ((int *) &flags)[0] = 0;
    q_core_f_object = NULL;
    shift_core_f_object.set_to_zero();
    cache_object = NULL;
    controller_phantom = NULL;

    strncpy(nocoll_group_ident, templ_obj->get_nocoll_group_ident(),IVP_NO_COLL_GROUP_STRING_LEN);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -