📄 ivp_compact_ledge_solver.hxx
字号:
// Copyright (C) Ipion Software GmbH 1999-2000. All rights reserved.
#ifdef SUN4
# define IVP_STATIC_INLINE inline
# define IVP_STATIC
#else
# define IVP_STATIC_INLINE static inline
# define IVP_STATIC static
#endif
#define IVP_MAGIC_INERTIA_RADIUS 100.0f // for ill calculated inertias use this default radius
#ifndef _IVP_CACHE_OBJECT_INCLUDED
# include <ivp_cache_object.hxx>
#endif
#ifndef _IVP_CACHE_LEDGE_POINT_INCLUDED
# include <ivp_cache_ledge_point.hxx>
#endif
class IVP_Cache_Ball;
class IVP_Unscaled_QR_Result {
public:
IVP_FLOAT checks[3]; // check[0] >0 -> inside this
IVP_FLOAT scale;
IVP_BOOL is_outside(){
unsigned int a = *((int *)&checks[0]);
unsigned int b = *((int *)&checks[1]);
unsigned int c = *((int *)&checks[2]);
unsigned int sign_bit = a | b | c;
return IVP_BOOL(sign_bit>>31);
}
};
class IVP_Unscaled_S_Result {
public:
IVP_FLOAT checks[2];
IVP_BOOL is_outside(){
unsigned int a = *((int *)&checks[0]);
unsigned int b = *((int *)&checks[1]);
unsigned int sign_bit = a | b;
return IVP_BOOL(sign_bit>>31);
}
};
class IVP_Unscaled_KK_Result {
public:
IVP_FLOAT checks_K[2]; // >0 means L projected onto K, K->next is on K->next side of K
IVP_FLOAT checks_L[2];
IVP_BOOL is_outside_K(){
unsigned int a = *((int *)&checks_K[0]);
unsigned int b = *((int *)&checks_K[1]);
unsigned int sign_bit = a | b;
return IVP_BOOL(sign_bit>>31);
}
IVP_BOOL is_outside_L(){
unsigned int a = *((int *)&checks_L[0]);
unsigned int b = *((int *)&checks_L[1]);
unsigned int sign_bit = a | b;
return IVP_BOOL(sign_bit>>31);
}
};
class IVP_KK_Input {
public:
const IVP_U_Float_Point *L_Los[2];
IVP_U_Point K_Los[2];
IVP_U_Point Kvec_Los;
IVP_U_Point Lvec_Los;
const IVP_Compact_Edge *K;
const IVP_Compact_Edge *L;
IVP_Cache_Ledge_Point *cache_K;
IVP_Cache_Ledge_Point *cache_L;
IVP_U_Point cross_KL_Los; // crossproduct of K vec and L vec
IVP_KK_Input( const IVP_Compact_Edge *K, const IVP_Compact_Edge *L, IVP_Cache_Ledge_Point *m_cache_K, IVP_Cache_Ledge_Point *m_cache_L);
IVP_DOUBLE calc_quad_distance_edge_edge();
};
class IVP_Compact_Ledge_Solver {
int dummy; // there are no zero length classes in some C++ compilers
public:
#ifdef DEBUG
IVP_STATIC IVP_BOOL check_ledge(const IVP_Compact_Ledge *c_ledge); // for debugging
#endif
/********************************************************************************
* Name: calc s_vals
* Description: find the point on an edge with the shortest distance to a given other point
* and return the position of that point on the edge as a relative
* value between 0 and 1: 0 means projected point is identical to first point of edge
* 1 means projected point is identical to second point od the edge
********************************************************************************/
IVP_STATIC_INLINE IVP_DOUBLE calc_dot_product_vec_dot_connection(const IVP_U_Point *vector, const IVP_U_Float_Point *s1, const IVP_U_Float_Point *e1);
IVP_STATIC IVP_DOUBLE calc_s_val(const IVP_Compact_Edge *edge, const IVP_U_Point *p_world, IVP_Cache_Ledge_Point *m_cache_edge); // calcs intersect pos
IVP_STATIC void calc_unscaled_s_val_K_space(const IVP_Compact_Ledge *c_ledge, const IVP_Compact_Edge *edge, const IVP_U_Point *P_Kos, IVP_Unscaled_S_Result *result);
/********************************************************************************
* Name: calc qr_vals
* Description: find the point on an area with the shortest distance to a given other point
* and return the position of that point on the edge as a relative
* values between 0 and 1:
* q, r refer to
* q=0, r=0 -> projected_point (pp) == this->next
* q=1, r=0 -> pp == this
* q=0, r=1 -> pp == this->prev
* q+r=1 -> pp == [this,this->prev]
********************************************************************************/
IVP_STATIC void calc_qr_vals(const IVP_Compact_Edge *e_tri,const IVP_Compact_Edge *p,
IVP_DOUBLE *out_q, IVP_DOUBLE *out_r,
IVP_Cache_Ledge_Point *m_cache_e_tri, IVP_Cache_Ledge_Point *m_cache_p);
IVP_STATIC void calc_qr_vals(const IVP_Compact_Edge *e_tri,const IVP_U_Point *p_world,
IVP_DOUBLE *out_q, IVP_DOUBLE *out_r,
IVP_Cache_Ledge_Point *m_cache_e_tri);
IVP_STATIC void calc_unscaled_qr_vals_F_space(const IVP_Compact_Ledge *c_ledge, const IVP_Compact_Edge *tri, const IVP_U_Point *object_point,
IVP_Unscaled_QR_Result *result);
/********************************************************************************
* Name: calc calc_unscaled_KK_vals
* Description: find the points on two edges with the shortest distance to each other
* and return the position of that points on the edges as a relative
* value between 0 and 1: 0 means projected point is identical to first point of edge
* 1 means projected point is identical to second point od the edge
********************************************************************************/
IVP_STATIC IVP_RETURN_TYPE calc_unscaled_KK_vals(const IVP_KK_Input &in, IVP_Unscaled_KK_Result *result);
/********************************************************************************
* Name: hesse vectors of an area
********************************************************************************/
IVP_STATIC void calc_hesse_normized_AT(const IVP_Compact_Edge *edge, IVP_Cache_Ledge_Point *cc, IVP_U_Hesse *hesse_out_ws);
IVP_STATIC void calc_hesse_object(const IVP_Compact_Edge *edge, const IVP_Compact_Ledge *ledge, IVP_U_Hesse *hesse_out_os);
IVP_STATIC void calc_hesse_vec_object_not_normized(const IVP_Compact_Edge *edge, const IVP_Compact_Ledge *ledge, IVP_U_Point *out_vec);
IVP_STATIC void calc_hesse_vec_object_not_normized(const IVP_Compact_Edge *edge, const IVP_Compact_Ledge *ledge, IVP_U_Float_Point *out_vec);
/********************************************************************************
* Name: minimize_on_other_side
* Description: Pierce through convex object and
* traverse triangles until valid q/r values (or valid term.len?).
* Returned edge represents the triangle found.
********************************************************************************/
IVP_STATIC const IVP_Compact_Edge *minimize_on_other_side(const IVP_Compact_Edge *edge, const IVP_U_Point *partner_this_os);
/********************************************************************************
* Name: various functions to get the coordinates of a point
********************************************************************************/
IVP_STATIC void give_world_coords_AT(const IVP_Compact_Edge *edge, IVP_Cache_Ledge_Point *clp, IVP_U_Point *p_ws_out);
IVP_STATIC inline const IVP_Compact_Poly_Point *give_object_coords(const IVP_Compact_Edge *edge, IVP_Cache_Ledge_Point *clp);
IVP_STATIC inline const IVP_Compact_Poly_Point *give_object_coords(const IVP_Compact_Edge *edge, const IVP_Compact_Ledge *ledge);
IVP_STATIC void calc_pos_other_space(const IVP_Compact_Edge *P,IVP_Cache_Ledge_Point *m_cache_P, IVP_Cache_Ledge_Point *m_cache_other_space, IVP_U_Point *res);
IVP_STATIC void transform_vec_other_space(const IVP_U_Point *dir_os, IVP_Cache_Ledge_Point *m_cache_dir, IVP_Cache_Ledge_Point *m_cache_other_space, IVP_U_Point *res);
IVP_STATIC void transform_pos_other_space(const IVP_U_Float_Point *pos_os, IVP_Cache_Ledge_Point *m_cache_pos, IVP_Cache_Ledge_Point *m_cache_other_space, IVP_U_Point *res);
/********************************************************************************
* Name: various functions to get the distance between two primitives
********************************************************************************/
IVP_STATIC IVP_DOUBLE quad_dist_edge_to_point_K_space(const IVP_Compact_Ledge *ledge_K, const IVP_Compact_Edge *K, const IVP_U_Point *object_pos);
IVP_STATIC IVP_DOUBLE calc_qlen_PP_P_space(const IVP_Compact_Ledge *P_ledge, const IVP_Compact_Edge *P,const IVP_U_Point *P_Pos);
IVP_STATIC IVP_DOUBLE calc_qlen_PK_K_space(const IVP_U_Point *P_in_K_space, const IVP_Compact_Ledge *K_ledge, const IVP_Compact_Edge *K );
IVP_STATIC IVP_DOUBLE calc_qlen_KK(const IVP_Compact_Edge *K,const IVP_Compact_Edge *L, IVP_Cache_Ledge_Point *m_cache_K, IVP_Cache_Ledge_Point *m_cache_L);
IVP_STATIC IVP_DOUBLE calc_qlen_PF_F_space(const IVP_Compact_Ledge *tri_ledge, const IVP_Compact_Triangle *tri,const IVP_U_Point *P_Fos);
/********************************************************************************
* Names: Convenience Routines
********************************************************************************/
IVP_STATIC void get_all_ledges(const class IVP_Compact_Ledgetree_Node *node, IVP_U_BigVector <IVP_Compact_Ledge> *ledges_out);
IVP_STATIC void get_all_ledges(const class IVP_Compact_Surface* surface, IVP_U_BigVector <IVP_Compact_Ledge>* ledges_out);
#ifdef HAVOK_MOPP
IVP_STATIC void get_all_ledges(const class IVP_Compact_Mopp* mopp, IVP_U_BigVector <IVP_Compact_Ledge>* ledges_out);
#endif // HAVOK_MOPP
/********************************************************************************
* Name: Bounding box and radius calculation
********************************************************************************/
private:
public:
IVP_STATIC void calc_bounding_box( const IVP_Compact_Ledge *c_ledge_in,
IVP_U_Point *min_extents_out, IVP_U_Point *max_extents_out);
IVP_STATIC void calc_radius_to_given_center( const IVP_Compact_Surface *c_surface_in, const IVP_U_Point *center_in,
IVP_DOUBLE *radius_out ,IVP_DOUBLE *radius_dev_out=0);
#ifdef HAVOK_MOPP
IVP_STATIC void calc_radius_to_given_center( const class IVP_Compact_Mopp* c_mopp_in, const IVP_U_Point *center_in,
IVP_DOUBLE *radius_out ,IVP_DOUBLE *radius_dev_out=0);
#endif // HAVOK_MOPP
IVP_STATIC void calc_radius_to_given_center( const IVP_Compact_Ledge *c_ledge, const IVP_U_Point *center_in, // note does not init radius_out and radius_dev_out
IVP_DOUBLE *radius_out ,IVP_DOUBLE *radius_dev_out=0);
IVP_STATIC void calc_geom_center_and_radius( const IVP_Compact_Ledge *c_ledge_in,
IVP_U_Point *geom_center_out, IVP_DOUBLE *geom_radius_out);
IVP_STATIC void calc_mass_center_and_radius( const IVP_Compact_Ledge *c_ledge_in,
IVP_U_Point *mass_center_out, IVP_DOUBLE *mass_radius_out);
};
extern IVP_Compact_Ledge_Solver IVP_CLS;
const IVP_Compact_Poly_Point *IVP_Compact_Ledge_Solver::give_object_coords(const IVP_Compact_Edge *edge, const IVP_Compact_Ledge *ledge){
IVP_ASSERT( ledge == edge->get_compact_ledge() );
int point_index = edge->get_start_point_index();
const IVP_Compact_Poly_Point *res = &ledge->get_point_array()[point_index];
return res;
}
const IVP_Compact_Poly_Point *IVP_Compact_Ledge_Solver::give_object_coords(const IVP_Compact_Edge *edge, IVP_Cache_Ledge_Point *clp)
{
IVP_ASSERT( clp->compact_ledge == edge->get_compact_ledge() );
int point_index = edge->get_start_point_index();
const IVP_Compact_Poly_Point *res = &clp->compact_poly_points[point_index];
IVP_ASSERT ( (int(res) & 15) == 0);
return res;
}
IVP_DOUBLE IVP_Compact_Ledge_Solver::calc_dot_product_vec_dot_connection(const IVP_U_Point *vector, const IVP_U_Float_Point *s0, const IVP_U_Float_Point *e0){
IVP_DOUBLE ax = e0->k[0] - s0->k[0];
IVP_DOUBLE ay = e0->k[1] - s0->k[1];
IVP_DOUBLE az = e0->k[2] - s0->k[2];
IVP_DOUBLE bx = ax * vector->k[0];
IVP_DOUBLE by = ay * vector->k[1];
IVP_DOUBLE bz = az * vector->k[2];
return bx + by + bz;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -