📄 ivp_friction.hxx
字号:
// 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 + -