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

📄 ivp_object_attach.cxx

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

#ifndef WIN32
#	pragma implementation "ivp_object_attach.hxx"
#endif

#include <ivp_physics.hxx>
#include <string.h>

#include <ivp_templates.hxx>
#include <ivp_cache_object.hxx>
#include <ivp_controller.hxx>
#include <ivp_calc_next_psi_solver.hxx>
#include <ivp_object_attach.hxx>
#include <ivp_hull_manager.hxx>
#include <ivp_hull_manager_macros.hxx>
#include <ivp_core_macros.hxx>
#include <ivp_mindist_intern.hxx>
#include <ivp_friction.hxx>

void IVP_Object_Attach::attach_object( IVP_Real_Object *parent, IVP_Real_Object *attached_object, 
				      IVP_DOUBLE max_distance_attached_object_to_parent ){

    if ( max_distance_attached_object_to_parent < 0.0f){
	// take current distance
	IVP_Time time = parent->get_environment()->get_current_time();
	IVP_U_Point parents_mass_center;
	parent->get_core()->inline_calc_at_position( time, &parents_mass_center);

	IVP_U_Point attached_mass_center;
	attached_object->get_core()->inline_calc_at_position( time, &attached_mass_center);

	max_distance_attached_object_to_parent = IVP_Inline_Math::sqrtd(parents_mass_center.quad_distance_to(&attached_mass_center));

    }


    // make sure both objects share the same state
    if ( IVP_MTIS_SIMULATED(parent->get_movement_state()) ){
	if ( !IVP_MTIS_SIMULATED(attached_object->get_movement_state()) ){
    	    attached_object->revive_object_for_simulation();
	}
    }else{
	if ( IVP_MTIS_SIMULATED(attached_object->get_movement_state()) ){
    	    parent->revive_object_for_simulation();
	}
    }

    IVP_Core *old_core = attached_object->get_core();

    IVP_Cache_Object *co = attached_object->get_cache_object_no_lock();
    IVP_U_Quat q_world_f_object = co->q_world_f_object;
    IVP_U_Point shift_world_f_object( co->m_world_f_object.get_position());

    IVP_Core *ncore = parent->get_core();

    // update radius
    IVP_DOUBLE radius = max_distance_attached_object_to_parent + old_core->upper_limit_radius;
    if (radius > ncore->upper_limit_radius){
	ncore->upper_limit_radius = radius;
    }

    IVP_DOUBLE max_surface_deviation = max_distance_attached_object_to_parent + old_core->max_surface_deviation;
    if (max_surface_deviation > ncore->max_surface_deviation){
	ncore->max_surface_deviation = max_surface_deviation;
    }	

    // exchange cores
    {
	old_core->unlink_obj_from_core_and_maybe_destroy( attached_object );
	attached_object->physical_core = ncore;
	attached_object->friction_core = ncore;
	attached_object->original_core = ncore;
	ncore->core_add_link_to_obj(attached_object);
    }
    {
	attached_object->flags.object_movement_state = parent->get_movement_state();
    }

    // position object
    reposition_object_Ros( NULL, attached_object, &q_world_f_object,  &shift_world_f_object, IVP_FALSE);

    // now update radius

    ncore->values_changed_recalc_redundants();
}

void IVP_Object_Attach::detach_object( IVP_Real_Object *attached_object, IVP_Template_Real_Object *t){

    // get rid of all contact points as they reference the core
    attached_object->unlink_contact_points(IVP_TRUE);


    IVP_Environment *env = attached_object->get_environment();
    IVP_Core *old_core = attached_object->get_core();

    // orientation
    IVP_U_Quat q_world_f_object;
    IVP_U_Point position_ws;

    {
        IVP_Cache_Object *co = attached_object->get_cache_object_no_lock();
	q_world_f_object = co->q_world_f_object;
	position_ws.set(co->m_world_f_object.get_position());
    }

    // velocity 
    IVP_U_Float_Point speed_ws;
    old_core->get_surface_speed_ws( &position_ws, &speed_ws);

    // angular velocity
    IVP_U_Float_Point rot_speed_cs;
    rot_speed_cs.set ( &old_core->rot_speed );

    // get the old center offset
    IVP_DOUBLE moved_distance_val = attached_object->get_shift_core_f_object()->real_length();


    // reset object values
    if(t->get_nocoll_group_ident()[0]){
	strncpy(attached_object->nocoll_group_ident, t->get_nocoll_group_ident(),IVP_NO_COLL_GROUP_STRING_LEN);
    }
    {  // get rid of old core
		int n_objs = old_core->objects.len();
			old_core->unlink_obj_from_core_and_maybe_destroy(attached_object);
		if (n_objs <= 1) old_core = 0; // mark core as deleted
		if (old_core) {
			old_core->values_changed_recalc_redundants();
		}
    }
    { // build new core
	attached_object->flags.object_movement_state = IVP_MT_NOT_SIM;
	attached_object->physical_core = new IVP_Core(attached_object, &q_world_f_object, &position_ws, IVP_FALSE /*physical_unmoveable*/,t->enable_piling_optimization);

	attached_object->friction_core = attached_object->physical_core;
	attached_object->original_core = attached_object->physical_core;

	if (t->material){
	    attached_object->l_default_material = t->material;
	}

	if (t->client_data){
	    attached_object->client_data = t->client_data;
	}
    
	attached_object->extra_radius = t->extra_radius;
	attached_object->init_object_core( env, t);
    }

    // set the new speed for next psi and wakeup object
    if ( IVP_MTIS_SIMULATED(old_core->movement_state)) {
	attached_object->get_core()->fire_event_object_frozen();		 // tell them that we went to sleep
	attached_object->ensure_in_simulation_now(); // wakeup and tell everybody
						  
	attached_object->get_core()->speed.set( &speed_ws );
	attached_object->get_core()->rot_speed.set( &rot_speed_cs );

	IVP_DOUBLE delta_time_till_next_PSI = env->get_next_PSI_time() - env->get_current_time();
	IVP_Vector_of_Hulls_128 active_hull_managers;
	IVP_Core *my_core= attached_object->get_core();
	if(!my_core->physical_unmoveable) {

   	    IVP_Hull_Manager *h_manager = attached_object->get_hull_manager();
	    h_manager->jump_add_hull(moved_distance_val,0.0f);


	    IVP_Event_Sim es(env, delta_time_till_next_PSI);
	    IVP_Calc_Next_PSI_Solver nps(my_core);
	    nps.calc_next_PSI_matrix(&es, &active_hull_managers);
	    my_core->tmp_null.old_sync_info=NULL;
   	    IVP_Calc_Next_PSI_Solver::commit_all_hull_managers( env,  &active_hull_managers);
	    attached_object->recalc_exact_mindists_of_object();
	    attached_object->update_exact_mindist_events_of_object();
	}
    }
}
    
    /********************************************************************************
    *	Name:	       	reposition_object_Ros.hxx
    *	Parameter:	q_Ros_f_Aos is a quat that transforms from Attached object space
    *			into Reference object space == matrix defining the attached object in Ros space
    *	Parameter:      check_before_moving if set movement will be limited if there
    *			might be penetration problems
    ********************************************************************************/
IVP_RETURN_TYPE IVP_Object_Attach::reposition_object_Ros( IVP_Real_Object *parent, IVP_Real_Object *attached_object,
						const IVP_U_Quat *q_Ros_f_Aos,
						const IVP_U_Point *shift_Ros_f_Aos,
						IVP_BOOL check_before_moving){

    IVP_U_Matrix m_world_f_Ros;
    if (parent){
	IVP_Cache_Object *co = parent->get_cache_object_no_lock();
	m_world_f_Ros = co->m_world_f_object;
    }else{
	m_world_f_Ros.init();
    }

    IVP_U_Matrix m_Ros_F_Aos;
    q_Ros_f_Aos->set_matrix( & m_Ros_F_Aos );
    m_Ros_F_Aos.get_position()->set(shift_Ros_f_Aos);

    IVP_U_Matrix m_ws_f_Aos;
    m_world_f_Ros.mmult4(&m_Ros_F_Aos, &m_ws_f_Aos);


    IVP_U_Matrix m_world_f_core;
    { // get current m_world_f_core
	IVP_Time current_time = attached_object->get_environment()->get_current_time();
	IVP_U_Quat q_world_f_core;
	attached_object->get_core()->inline_calc_at_quaternion(current_time, &q_world_f_core);
	q_world_f_core.set_matrix( & m_world_f_core );
	attached_object->get_core()->inline_calc_at_position(current_time, &m_world_f_core.vv);
    }

    IVP_U_Matrix m_Aos_f_Rcs;   m_ws_f_Aos.mimult4( &m_world_f_core, &m_Aos_f_Rcs);

    attached_object->set_new_m_object_f_core(&m_Aos_f_Rcs);

    IVP_DOUBLE diff = 0.01f;		    // hopefully we wont get an endless loop
    IVP_DOUBLE moved_distance_val = 0.0f; // center movement 

	IVP_Hull_Manager *h_manager = attached_object->get_hull_manager();
	h_manager->jump_add_hull(diff,moved_distance_val);

	IVP_Cache_Object_Manager::invalid_cache_object(attached_object);
	attached_object->recalc_exact_mindists_of_object();
	attached_object->recalc_invalid_mindists_of_object();

	h_manager->check_hull_synapses();
	h_manager->check_for_reset();

    return IVP_OK;
}

⌨️ 快捷键说明

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