📄 vm_query_builder.h
字号:
#ifndef HK_PHYSICS_VM_QUERY_BUILDER
#define HK_PHYSICS_VM_QUERY_BUILDER
#include <hk_math/densematrix.h>
#include <hk_math/dense_vector.h>
#include <hk_physics/core/vm_query_builder/mass_relative_vector3.h>
#include <hk_physics/core/vm_query.h>
// IVP_EXPORT_PUBLIC
#ifndef HK_TRANSFORM_TO_CORE_SPACE // for ipion compatibility
# define HK_TRANSFORM_TO_CORE_SPACE(body,vector)
#endif
#define HK_MAX_IMPULSE 1e3
template <int N>
class hk_VMQ_Storage
{
public:
inline hk_VMQ_Storage() { }
inline ~hk_VMQ_Storage(){ }
inline void initialize()
{
m_dense_matrix.set_zero();
clear_velocities();
}
inline void clear_velocities()
{
hk_Vector4* p = (hk_Vector4*) (&m_velocities[0]);
for( int i= ((N-1)>>2); i>=0; p++, i--)
{
p->set_zero4();
}
}
inline int length() { return N; }
inline hk_Dense_Matrix& get_dense_matrix()
{ return m_dense_matrix; }
inline hk_Fixed_Dense_Matrix<N>& get_fixed_dense_matrix()
{ return m_dense_matrix; }
inline hk_Cached_Force_Axis_Description* get_cfad_buffer_0()
{ return (hk_Cached_Force_Axis_Description *)&m_buffer_0[0]; }
inline hk_Cached_Force_Axis_Description* get_cfad_buffer_1()
{ return (hk_Cached_Force_Axis_Description *)&m_buffer_1[0]; }
inline hk_real *get_velocities() { return m_velocities; }
inline hk_Virtual_Mass_Query *get_vmq(int x)
{ return (hk_Virtual_Mass_Query *)&m_impulse_info[x][0]; }
protected:
hk_real m_velocities[ HK_NEXT_MULTIPLE_OF(4,N) ];
char m_buffer_0[ HK_MAX_SIZEOF_CACHED_FORCE_AXIS_DESCRIPTION * N];
char m_buffer_1[ HK_MAX_SIZEOF_CACHED_FORCE_AXIS_DESCRIPTION * N];
hk_real HK_ALIGNED_VARIABLE(m_impulse_info[2][sizeof( hk_Virtual_Mass_Query ) * N / sizeof( hk_real)],16);
hk_Fixed_Dense_Matrix<N> m_dense_matrix;
};
// Note T is a storage class for hk_VM_Query_Builder
// see hk_VMQ_Storage_3 public elements for details
//
enum hk_Body_Index
{
HK_BODY_A = 0,
HK_BODY_B = 1
};
enum hk_Axis_Index
{
HK_X_DIRECTION = 0,
HK_Y_DIRECTION = 1,
HK_Z_DIRECTION = 2
};
template<class T>
class hk_VM_Query_Builder
{
public:
inline hk_VM_Query_Builder(){}
void begin(int size)
{
m_input[0].m_buffer = m_vmq_storage.get_cfad_buffer_0();
m_input[1].m_buffer = m_vmq_storage.get_cfad_buffer_1();
m_input[0].m_vmq = m_vmq_storage.get_vmq(0);
m_input[1].m_vmq = m_vmq_storage.get_vmq(1);
m_vmq_offset = 0;
m_dense_matrix_offset = 0;
m_vmq_storage.initialize();
}
inline T& get_vmq_storage()
{
return m_vmq_storage;
}
inline void begin_entries(int size) {}
inline void add_angular(
int index_offset,
hk_Body_Index body_index,
hk_Rigid_Body *rb,
const hk_Vector3 &axis_ws,
hk_real sign )
{
HK_ASSERT( int(index_offset + m_vmq_offset/sizeof(hk_Virtual_Mass_Query)) < m_vmq_storage.length() );
hk_Virtual_Mass_Query &vmq = *offset_vmq (m_vmq_storage.get_vmq(body_index), index_offset);
vmq.m_linear.set_zero();
vmq.m_angular.set_mul( sign, axis_ws );
HK_TRANSFORM_TO_CORE_SPACE( rb, vmq.m_angular );
vmq.m_matrix_index = m_dense_matrix_offset + index_offset;
vmq.m_entity_core_id = rb->get_entity_core_id();
}
inline void add_linear( int index_offset, hk_Body_Index body_index, hk_Rigid_Body *rb,
const hk_Vector3 &position_ws, const hk_Vector3 &direction_ws, hk_real signum )
{
HK_ASSERT( int(index_offset + m_vmq_offset/sizeof(hk_Virtual_Mass_Query)) < m_vmq_storage.length() );
hk_Virtual_Mass_Query &vmq = *offset_vmq (m_vmq_storage.get_vmq(body_index), index_offset);
hk_Vector3 mass_center_relative; mass_center_relative.set_sub( position_ws, rb->get_center_of_mass() );
vmq.m_linear.set_mul( signum, direction_ws);
vmq.m_angular.set_cross( mass_center_relative, vmq.m_linear );
HK_TRANSFORM_TO_CORE_SPACE( rb, vmq.m_angular );
vmq.m_matrix_index = m_dense_matrix_offset + index_offset;
vmq.m_entity_core_id = rb->get_entity_core_id();
}
inline void add_linear( int index_offset, hk_Body_Index body_index, hk_Rigid_Body *rb,
const hk_Mass_Relative_Vector3 &pos_rel, const hk_Vector3 &direction_ws, hk_real signum )
{
HK_ASSERT( int(index_offset + m_vmq_offset/sizeof(hk_Virtual_Mass_Query)) < m_vmq_storage.length() );
hk_Virtual_Mass_Query &vmq = *offset_vmq (m_vmq_storage.get_vmq(body_index), index_offset);
const hk_Vector3 &mass_center_relative = pos_rel.m_vector;
vmq.m_linear.set_mul( signum, direction_ws);
vmq.m_angular.set_cross( mass_center_relative, vmq.m_linear );
HK_TRANSFORM_TO_CORE_SPACE( rb, vmq.m_angular );
vmq.m_matrix_index = m_dense_matrix_offset + index_offset;
vmq.m_entity_core_id = rb->get_entity_core_id();
}
inline void add_linear_xyz( int index_offset, hk_Axis_Index axis,
hk_Body_Index body_index, hk_Rigid_Body *rb,
const hk_Mass_Relative_Vector3 &mass_center_relative, hk_real signum)
{
HK_ASSERT( int(index_offset + m_vmq_offset/sizeof(hk_Virtual_Mass_Query)) < m_vmq_storage.length() );
hk_Virtual_Mass_Query &vmq = *offset_vmq (m_vmq_storage.get_vmq(body_index), index_offset);
vmq.m_linear.set_zero();
vmq.m_linear( axis ) = signum;
const hk_Vector3 &mcr = mass_center_relative.m_vector;
#if 1
if (axis == 0){ vmq.m_angular.set( 0.0f, signum * mcr.z, -mcr.y * signum );
}else if ( axis == 1){ vmq.m_angular.set( -mcr.z * signum, 0.0f, mcr.x *signum );
}else{ vmq.m_angular.set( mcr.y * signum, -mcr.x * signum, 0.0f );
}
#else
vmq.m_angular.set_cross( mcr, vmq.m_linear );
#endif
HK_TRANSFORM_TO_CORE_SPACE( rb, vmq.m_angular );
/*
{ // ipion check hack
IVP_U_Float_Point dir_ws( vmq.m_linear(0), vmq.m_linear(1),vmq.m_linear(2) );
IVP_U_Float_Point dir_cs;
rb->get_core()->get_m_world_f_core_PSI()->vimult3( &dir_ws, &dir_cs );
IVP_U_Float_Point pos_ws( mass_center_relative(0), mass_center_relative(1), mass_center_relative(2) );
IVP_U_Float_Point pos_cs;
rb->get_core()->get_m_world_f_core_PSI()->vimult3( &pos_ws, &pos_cs );
IVP_U_Float_Point cross_cs;
cross_cs.inline_calc_cross_product( &pos_cs, &dir_cs );
ivp_message("hav %1.3f %1.3f %1.3f ipion %1.3f %1.3f %1.3f\n", vmq.m_angular.x, vmq.m_angular.y, vmq.m_angular.z, cross_cs.k[0], cross_cs.k[1], cross_cs.k[2]);
}
// */
vmq.m_matrix_index = m_dense_matrix_offset + index_offset;
vmq.m_entity_core_id = rb->get_entity_core_id();
}
inline void commit_entries(int size)
{
m_dense_matrix_offset += size;
m_vmq_offset += size * sizeof( hk_Virtual_Mass_Query );
}
inline void commit(hk_Body_Index body_index, hk_Rigid_Body *rb)
{
m_input[0].m_n_queries = m_dense_matrix_offset;
m_input[1].m_n_queries = m_dense_matrix_offset;
hk_Rigid_Body_Core *core = rb->get_rigid_body_core();
hk_Dense_Matrix &matrix = m_vmq_storage.get_dense_matrix();
hk_real *velocities = m_vmq_storage.get_velocities();
core->add_to_mass_matrix_inv( m_input[ body_index ],matrix, velocities);
}
inline void clear_velocities(hk_Body_Index body_index, hk_Rigid_Body *rb)
{
m_vmq_storage.clear_velocities();
}
inline void update_velocities(hk_Body_Index body_index, hk_Rigid_Body *rb)
{
rb->get_rigid_body_core()->add_to_velocities( m_input[ body_index ],
m_vmq_storage.get_velocities());
}
inline void apply_impulses( hk_Body_Index body_index, hk_Rigid_Body *rb,
const hk_real impulses[] )
{
HK_IF_CHECK (HK_FALSE)
{
for (int i = 0; i < m_dense_matrix_offset;i++)
{
HK_CHECK( impulses[i] < HK_MAX_IMPULSE );
}
}
rb->get_rigid_body_core()->apply_impulses( m_input[ body_index ], impulses);
}
protected:
T m_vmq_storage;
hk_Core_VMQ_Input m_input[2];
unsigned int m_vmq_offset;
int m_dense_matrix_offset;
inline hk_Virtual_Mass_Query *offset_vmq( hk_Virtual_Mass_Query *base, int index )
{
return (hk_Virtual_Mass_Query *) ( ((char *)&base[index]) + m_vmq_offset );
}
};
/* Typical usage of this class :
*
* VMQB.begin();
* for ( xxx ){
* VMQB.begin_entry()
* VMQB.add_linear ( first_body.... ) or something else
* [VMQB.add_linear ( second_body ... ) ] only if second body exists
* VMQB.commit_entry()
* }
* VMQB.commit(0, first_body, 1.0f)
* [VMQB.commit(1, second_body, -1.0f)] only if second body exists
*
*/
#endif /* HK_PHYSICS_VM_QUERY_BUILDER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -