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

📄 ivp_friction.hxx

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

//Datastructures for friction systems:
//    Vector of all objects (IVP_Real_Object) belonging to fr sys, objects are counted: friction_obj_number
//        every object has Vector of IVP_Friction_Info_For_Obj for every friction system it belongs to (one object can have more then one fr sys,but now used only for fixed objects)
//            in one IVP_Friction_Info_For_Obj is Vector of IVP_Contact_Point and a backlink to friction system
//    Vector IVP_Friction_Core_Pair for every pair of objects that share mindists (for easing friction forces and speedup of union find)
//        every pair has backlinks to objects and Vector of IVP_Contact_Point that have that object pair as anchors
//    double linked list of all IVP_Contact_Point belonging to fr sys, dists are counted: friction_dist_number
//        IVP_Contact_Point has backlink to both objects (via snapses ...)
//        IVP_Contact_Point are numbered (but counted oppositely the way they occur in the list)
//    function test_hole_fr_system_data checks consistency of most of this infos 

class IVP_Contact_Point;
class IVP_Friction_Solver_Long_Term;
class IVP_Mindist_Manager;
class IVP_Core;
class IVP_Friction_Info_For_Core;
class IV_U_Point_PCore;
class IVP_Environment;
class IVP_Cache_Ledge_Point;
class IVP_Compact_Edge;

#define IVP_SLOWLY_TURN_ON_KEEPER 20

#define IVP_MAX_FRICTION_MATRIX 150
#define IVP_MAX_ADHESION_GAUSS 0.01f //in percent of weight

#define IVP_MINIMAL_REAL_FRICTION_LEN 0.005f
//#define NOFRICTIONFORCE
//#define NOEASING 
//#define NO_MUTUAL_ENERGYDESTROY
//#define INTEGRATE_ENERGY_DAMP 0.9f //leave 
#define MAX_ENERGY_DESTROY 0.1f
#define IVP_EASE_EVERY_NTH_PSI 5
//#define IVP_USE_S_VALS_FOR_PRETENSION

//#define IVP_DISTANCE_KEEPERS
//#define IVP_PANELTY_SOLVER


#ifndef IVP_CONTROLLER_INCLUDED
#	include <ivp_controller.hxx>
#endif

#ifndef _IVP_CONTACT_SITUATION_INCLUDED
#	include <ivp_contact_situation.hxx>
#endif

// set completely (except union) by recalc friction s_vals
class IVP_Impact_Solver_Long_Term : public IVP_Contact_Situation {
public:
    short    index_in_fs;
    short    impacts_while_system;   
    IVP_BOOL coll_time_is_valid:8;
    IVP_BOOL friction_is_broken:2;
    // next block is mantained by calc_coll_dist and needed by impact

    union {
	struct { // impact data
	    IVP_FLOAT rescue_speed_addon;
	    IVP_FLOAT distance_reached_in_time;
	    IVP_FLOAT percent_energy_conservation; // #+# maybe move to IVP_Contact_Point, maybe short 1.0f subtract energy destroyed
	} impact;
	// next block is used for friction and set by IVP_Friction_Solver::setup_coords_mindists
	struct { // friction data
	    IVP_Friction_Info_For_Core *friction_infos[2]; //two friction infos for one distance, to get all distances of a object  x2
	    int has_negative_pull_since;                   // copy of contact point to avoid cache misses
	    IVP_FLOAT dist_len;                            // copy of distance of two objects now    
	} friction;
    };
    IVP_FLOAT  virtual_mass;             // in direction of surface normal
    IVP_FLOAT  inv_virtual_mass;         // in direction of surface normal
    
    IVP_Core *contact_core[2];                    // == 0 for unmoveable cores

    IVP_U_Float_Point span_friction_v[2]; // orthogonal vectors in world coords
    // vector of v[0]*s[0] + v[1]*s[1] is real world force vector of force that has to be done on first obj (is pointing to second obj)
 
    IVP_U_Float_Point contact_point_cs[2];   // impact/friction position in core coordinates
    IVP_U_Float_Point contact_cross_nomal_cs[2]; // crossproduct of contact_point_cs and normal_cs


  // *******************
  // ******** functions:
  // *******************    
    void init_tmp_contact_info() { impacts_while_system=0; coll_time_is_valid=IVP_FALSE; friction_is_broken = IVP_FALSE; };
  
    IVP_Impact_Solver_Long_Term() { init_tmp_contact_info(); };

    inline IVP_DOUBLE get_closing_speed() const ;  // based on current core speed
    
    void do_impact_long_term(IVP_Core *pushed_cores[2], IVP_FLOAT rescue_speed_val, IVP_Contact_Point *cp); // returns 0 if O.K. , returns 1 if false impact
    static IVP_Core *find_second_critical_impact_core(IVP_Core *core1,IVP_Core *core0);
    
    // the real start of an impact
    static void do_impact_of_two_objects(IVP_Mindist *mindist, IVP_Real_Object *obj0,IVP_Real_Object *obj1);
    static IVP_Core *get_best_merge_core(IVP_Core *core0,IVP_Core *core1,IVP_Core *core2);
};


class IVP_Synapse_Friction {  // sizeof() == 32
public:
  IVP_Synapse_Friction 	 *next, *prev;		        // per object list
  IVP_Real_Object  *l_obj;				// back link to object
protected:
  short contact_point_offset;               // back link to my controlling mindist
  short status:8;			    // type IVP_SYNAPSE_POLYGON_STATUS  point, edge, tri, ball ....
public:
    
  const IVP_Compact_Edge 	*edge;		// Note: all balls share one dummy edge


    // has to be transfered to synapse_friction_polygon:

    IVP_Real_Object *get_object(){ return l_obj; };
    IVP_Synapse_Friction       *get_next(){ return next;};
    IVP_Synapse_Friction       *get_prev(){ return prev;};
    IVP_Contact_Point *get_contact_point()const{ return  (IVP_Contact_Point *)(contact_point_offset + (char *)this);};
    void set_contact_point( IVP_Contact_Point *cp ) { contact_point_offset = ((char *)cp) - (char *)this; };

    int                        get_material_index() const;
    IVP_SYNAPSE_POLYGON_STATUS get_status()const { return (IVP_SYNAPSE_POLYGON_STATUS)status; }
    inline void init_synapse_friction(IVP_Contact_Point *friction,
	    		    IVP_Real_Object *object,
			    const IVP_Compact_Edge 	*edge,
			    IVP_SYNAPSE_POLYGON_STATUS status);

    IVP_BOOL is_same_as(const IVP_Synapse_Real *syn_comp) const;
    inline void remove_friction_synapse_from_object();  // @@@OS insert fr ????
};

//  now_friction_pressure: force done by complex SI:  t*m / s*s
//     This force is: push * inv_delta_PSI_time
//     SI of push: t*m / s
//  real_fr_now_len is length of horizontal friction spring
//     Real friction force done on objects horizontal: (now_friction_pressure * inv_max_len * friction_factor)  *  real_fr_now_len    .SI:  t*m / s*s
//     Corresponding D of horizontal spring: now_friction_pressure * inv_max_len * friction_factor     .SI:  t / s*s
//     Energy stored in horizontal spring:  0.5f * D * real_fr_now_len*real_fr_now_len   . SI:  t*m*m / s*s
//  Pot Energy won by complex: now_friction_pressure * delta Distance.    SI:  t*m*m / s*s 

// fast static area
class IVP_Contact_Point_Fast_Static {
protected:

    IVP_Contact_Point *next_dist_in_friction; // all friction springs in a friction system
    IVP_Contact_Point *prev_dist_in_friction;

    IVP_Synapse_Friction       synapse[2];

    //for real friction
    IVP_FLOAT inv_virt_mass_mindist_no_dir; 

    IVP_BOOL two_friction_values:8;
};

enum IVP_CONTACT_POINT_BREAK_STATUS {
    IVP_CPBS_NORMAL,
    IVP_CPBS_NEEDS_RECHECK,
    IVP_CPBS_BROKEN
};

// add fast dynamics
class IVP_Contact_Point_Fast: public IVP_Contact_Point_Fast_Static {
protected:
#ifdef IVP_USE_S_VALS_FOR_PRETENSION
    IVP_FLOAT s_coords[2];	    //
#endif    
    IVP_FLOAT span_friction_s[2];

    IVP_Impact_Solver_Long_Term *tmp_contact_info;

    IVP_FLOAT real_friction_factor;          // the friction factor
    
    IVP_FLOAT integrated_destroyed_energy;   // for watching a contact point over time, e.g. to drive the sound engine
    IVP_FLOAT inv_triangle_det;              // to optimize pF cases
    // for energy difference calculations
    IVP_FLOAT old_energy_dynamic_fr;
    IVP_FLOAT now_friction_pressure; // needed to add values  distance_keeper pressure + static friction
    IVP_FLOAT last_gap_len; //length of gap at last PSI (to calc gained energy)
    
    IVP_FLOAT get_gap_length() { return last_gap_len; };
    
    short slowly_turn_on_keeper;     // is initialized with IVP_SLOWLY_TURN_ON_KEEPER
    IVP_CONTACT_POINT_BREAK_STATUS  cp_status:8;
    int has_negative_pull_since;   //0 means inactive, n>1 means negative since n-1 PSIs, -n>0 means has positive value since n PSIs
    IVP_Time last_time_of_recalc_friction_s_vals; // move to friction system
    IVP_U_Float_Point last_contact_point_ws;
};

class IVP_Contact_Point: public IVP_Contact_Point_Fast {
    friend class IVP_Real_Object;
    friend class IVP_Core;
    friend class IVP_Friction_Solver;
    friend class IVP_Impact_Solver_Long_Term;
    friend class IVP_Impact_Solver;
    friend class IVP_Friction_System;
    friend class IVP_Friction_Sys_Static;
    friend class IVP_Impact_System;
    friend class IVP_Friction_Core_Pair;
    friend class IVP_Contact_Point_API;

    friend class IVP_Mindist;
    friend class IVP_Friction_Manager;

    IVP_Friction_System *l_friction_system; //backlink for deleting
    
    IVP_BOOL is_same_as(const IVP_Mindist *md2) const;

    // impact system
    void get_cos_sin_for_impact(IVP_FLOAT friction_val,IVP_FLOAT *cos_val,IVP_FLOAT *sin_val);
    void read_materials_for_contact_situation(IVP_Impact_Solver_Long_Term *info); // #+# check calls to this function when material is changed on the fly -> recalc some values

    void calc_coll_distance(); // returns the distance reached in one PSI and the rescue speed val and stores result in impact.distance_reached_in_time

    IVP_FLOAT get_rot_speed_uncertainty();
    IVP_FLOAT get_rescue_speed_impact(IVP_Environment *);
    
    inline IVP_FLOAT get_possible_friction_slide_way(const IVP_Event_Sim *es);
   
    void debug_situation_after_impact();    
  
    void calc_spring_constant_mindist_distance_keeper();
    void calc_virtual_mass_of_mindist();
    void update_distance_keepers_both_cores();
    
    /*** for friction mode ***/
    // for friction mode
    void leave_friction_mode();
    void reset_time(IVP_Time offset);
    
    //for easing friction forces
    void ease_the_friction_force(IVP_U_Float_Point *diff_vec);  // #+#, call only randomly, create flag for sliding

    //for doing real friction
    void friction_force_local_constraint_1d(const IVP_Event_Sim *);
    IVP_FLOAT friction_force_local_constraint_2d(const IVP_Event_Sim *);
	bool friction_force_local_constraint_2d_wheel( IVP_Core *core_a, IVP_Impact_Solver_Long_Term *info, const IVP_Event_Sim *es, IVP_FLOAT &flEnergy );
    void static_friction_single(const IVP_Event_Sim *es,IVP_FLOAT dg,IVP_FLOAT speedup_factor);
    IVP_BOOL get_world_direction_second_friction(IVP_U_Float_Point *ret_second_friction_vec,IVP_FLOAT *sin_second_friction);
    IVP_DOUBLE two_values_friction(IVP_U_Float_Point *real_world_friction_vec);
    IVP_DOUBLE get_and_set_real_friction_len(IVP_U_Float_Point *real_world_friction_vec);

    inline void calc_pretension(IVP_FLOAT len);

    IVP_Impact_Solver_Long_Term *get_lt(){ return tmp_contact_info; };
    
    ~IVP_Contact_Point();
    // some friction checks:

⌨️ 快捷键说明

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