Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _USE_MATH_DEFINES
- #include <math.h>
- #include <string.h>
- #include <assert.h>
- #include <float.h>
- #include "vec2d.h"
- #define PI 3.14159265358979323846f
- inline float rad2deg( float x )
- {
- return x / PI * 180;
- }
- inline float deg2rad( float x )
- {
- return x * PI / 180;
- }
- inline float sign( float x )
- {
- return x == 0.0f ? 0.0f : ( x > 0.0f ? 1.0f : -1.0f );
- }
- inline float lerp( float a, float b, float s )
- {
- return a + ( b - a ) * s;
- }
- template< typename _T >
- _T min( _T a, _T b )
- {
- if( a < b ) return a;
- else return b;
- }
- template< typename _T >
- _T max( _T a, _T b )
- {
- if( a > b ) return a;
- else return b;
- }
- #define TY_NORMAL 0
- #define TY_SPEC_LD 1
- #define TY_SPEC_RD 2
- struct box_t
- {
- vec2d min;
- vec2d max;
- int type;
- };
- struct ball_t
- {
- vec2d pos,
- vel,
- acc;
- float radius;
- float friction,
- restitution,
- avel,
- angle;
- };
- int __real_box_size;
- ball_t* g_ball;
- box_t* g_boxes;
- int g_box_count;
- vec2d g_col_normal;
- inline bool aabb_collide( const box_t& b1, const box_t& b2 )
- {
- return ( ( b1.min.x < b2.max.x || b2.min.x < b1.max.x ) &&
- ( b1.min.y < b2.max.y || b2.min.y < b1.max.y ) );
- }
- inline bool aabb_point_collide( const box_t& box, vec2d& pos )
- {
- return ( pos.x >= box.min.x && pos.x <= box.max.x &&
- pos.y >= box.min.y && pos.y <= box.max.y );
- }
- inline bool aa_1d_collide( const float f1a, const float f1b, const float f2a, const float f2b )
- {
- return ( f1a < f2b || f2a < f1b );
- }
- /*
- void fill_proxy( const vec2d& next_pos )
- {
- vec2d m_normal( -g_ball->vel.y, g_ball->vel.x );
- m_normal.normalize();
- float p_min = m_normal * g_ball->pos - g_ball->radius;
- float p_max = m_normal * g_ball->pos + g_ball->radius;
- vec2d bb_min( min( next_pos.x, g_ball->pos.x ) - g_ball->radius, min( next_pos.y, g_ball->pos.y ) - g_ball->radius );
- vec2d bb_max( max( next_pos.x, g_ball->pos.x ) + g_ball->radius, max( next_pos.y, g_ball->pos.y ) + g_ball->radius );
- box_t aabb = { bb_min, bb_max, 0 };
- g_proxy_size = 0;
- for( int i = 0; i < g_box_count; ++i )
- {
- if( aabb_collide( aabb, *g_boxes[ i ] ) )
- {
- float p1 = m_normal * g_boxes[ i ]->min;
- float p2 = m_normal * g_boxes[ i ]->max;
- float p3 = m_normal * vec2d( g_boxes[ i ]->max.x, g_boxes[ i ]->min.y );
- float p4 = m_normal * vec2d( g_boxes[ i ]->min.x, g_boxes[ i ]->max.y );
- float pbmin = min( p1, p2 ); pbmin = min( pbmin, p3 ); pbmin = min( pbmin, p4 );
- float pbmax = max( p1, p2 ); pbmax = max( pbmax, p3 ); pbmax = max( pbmax, p4 );
- if( aa_1d_collide( pbmin, pbmax, p_min, p_max ) )
- {
- g_proxy[ g_proxy_size ] = g_boxes[ i ];
- g_proxy_size++;
- }
- }
- }
- }
- */
- const float MIN_TIMEPT = 0.001f;
- const float PUSHOUT_K = 1.01f;
- const float GETIN_K = 0.99f;
- /// Collision function
- /// Ball - Box
- /// Ball can collide with edges and vertices of the box
- float ball_box_collision_t0( const box_t* box, const vec2d& next_pos, float max_time )
- {
- vec2d m_normal( -g_ball->vel.y, g_ball->vel.x );
- m_normal.normalize();
- float p_mid = m_normal * g_ball->pos;
- float p_min = p_mid - g_ball->radius;
- float p_max = p_mid + g_ball->radius;
- vec2d m_vdir = next_pos - g_ball->pos;
- vec2d m_vel = m_vdir;
- float v_length = m_vdir.length();
- m_vdir /= v_length;
- vec2d b_p1 = box->min;
- vec2d b_p2 = vec2d( box->max.x, box->min.y );
- vec2d b_p3 = box->max;
- vec2d b_p4 = vec2d( box->min.x, box->max.y );
- /// collision data
- vec2d col_normal( 0, 0 );
- float col_time = max_time;
- vec2d D;
- float len, d, c, c2;
- bool col = false;
- /// Edge 1
- c = box->min.y - g_ball->radius;
- d = ( c - g_ball->pos.y ) / ( next_pos.y - g_ball->pos.y );
- c2 = g_ball->pos.x + m_vdir.x * d;
- if( d > 0 && c2 >= box->min.x && c2 <= box->max.x && d <= col_time )
- {
- col_time = d;
- col_normal.set( 0, -1 );
- col = true;
- }
- /// Edge 2
- c = box->max.x + g_ball->radius;
- d = ( c - g_ball->pos.x ) / ( next_pos.x - g_ball->pos.x );
- c2 = g_ball->pos.y + m_vdir.y * d;
- if( d > 0 && c2 >= box->min.y && c2 <= box->max.y && d <= col_time )
- {
- col_time = d;
- col_normal.set( 1, 0 );
- col = true;
- }
- /// Edge 3
- c = box->max.y + g_ball->radius;
- d = ( c - g_ball->pos.y ) / ( next_pos.y - g_ball->pos.y );
- c2 = g_ball->pos.x + m_vdir.x * d;
- if( d > 0 && c2 >= box->min.x && c2 <= box->max.x && d <= col_time )
- {
- col_time = d;
- col_normal.set( 0, 1 );
- col = true;
- }
- /// Edge 4
- c = box->min.x - g_ball->radius;
- d = ( c - g_ball->pos.x ) / ( next_pos.x - g_ball->pos.x );
- c2 = g_ball->pos.y + m_vdir.y * d;
- if( d > 0 && c2 >= box->min.y && c2 <= box->max.y && d <= col_time )
- {
- col_time = d;
- col_normal.set( -1, 0 );
- col = true;
- }
- vec2d col_pt;
- vec2d col_unmax;
- float len_unmax;
- /// Vertex 1
- D = b_p1 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p1 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p1 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p1;
- col_normal.normalize();
- col = true;
- }
- }
- /// Vertex 2
- D = b_p2 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p2 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p2 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p2;
- col_normal.normalize();
- col = true;
- }
- }
- /// Vertex 3
- D = b_p3 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p3 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p3 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p3;
- col_normal.normalize();
- col = true;
- }
- }
- /// Vertex 4
- D = b_p4 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p4 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p4 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p4;
- col_normal.normalize();
- col = true;
- }
- }
- /// Before returning, check the ball
- vec2d center = ( box->min + box->max ) * 0.5f;
- vec2d extents = box->max - center;
- vec2d ptb = g_ball->pos - center;
- if( ptb.x < -extents.x ) ptb.x = -extents.x;
- if( ptb.x > extents.x ) ptb.x = extents.x;
- if( ptb.y < -extents.y ) ptb.y = -extents.y;
- if( ptb.y > extents.y ) ptb.y = extents.y;
- vec2d ptn = ptb;
- ptn.normalize();
- if( ( g_ball->pos - ptb - center ).length() < g_ball->radius )
- {
- if( aabb_point_collide( *box, g_ball->pos ) )
- {
- vec2d normal = ptb;
- if( abs( normal.x ) > abs( normal.y ) )
- {
- g_ball->pos.x = center.x + sign( normal.x ) * ( extents.x + g_ball->radius ) * PUSHOUT_K;
- g_col_normal.set( sign( normal.x ), 0 );
- return MIN_TIMEPT;
- }
- else
- {
- g_ball->pos.y = center.y + sign( normal.y ) * ( extents.y + g_ball->radius ) * PUSHOUT_K;
- g_col_normal.set( 0, sign( normal.y ) );
- return MIN_TIMEPT;
- }
- }
- else
- {
- vec2d normal = g_ball->pos - ptb - center;
- normal.normalize();
- g_col_normal = normal;
- g_ball->pos = center + ptb * PUSHOUT_K + normal * g_ball->radius;
- return MIN_TIMEPT;
- }
- }
- if( col == false ) return -1;
- g_col_normal = col_normal;
- return col_time;
- }
- /// Collision function
- /// Ball - Box + circle inside cut ; edges - left/down
- /// Ball can collide with edges and vertices and the slope of the "box"
- float ball_box_collision_tldi( const box_t* box, const vec2d& next_pos, float max_time )
- {
- vec2d m_normal( -g_ball->vel.y, g_ball->vel.x );
- m_normal.normalize();
- float p_mid = m_normal * g_ball->pos;
- float p_min = p_mid - g_ball->radius;
- float p_max = p_mid + g_ball->radius;
- vec2d m_vdir = next_pos - g_ball->pos;
- vec2d m_vel = m_vdir;
- float v_length = m_vdir.length();
- m_vdir /= v_length;
- vec2d b_p1 = box->min;
- vec2d b_p2 = vec2d( box->max.x, box->min.y );
- vec2d b_p3 = box->max;
- vec2d b_p4 = vec2d( box->min.x, box->max.y );
- /// collision data
- vec2d col_normal( 0, 0 );
- float col_time = max_time;
- vec2d D;
- float len, d, c, c2;
- bool col = false;
- /// Edge 1 EMPTY
- /// Edge 2 EMPTY
- /// Edge 3
- c = box->max.y + g_ball->radius;
- d = ( c - g_ball->pos.y ) / ( next_pos.y - g_ball->pos.y );
- c2 = g_ball->pos.x + m_vdir.x * d;
- if( d > 0 && c2 >= box->min.x && c2 <= box->max.x && d <= col_time )
- {
- col_time = d;
- col_normal.set( 0, 1 );
- col = true;
- }
- /// Edge 4
- c = box->min.x - g_ball->radius;
- d = ( c - g_ball->pos.x ) / ( next_pos.x - g_ball->pos.x );
- c2 = g_ball->pos.y + m_vdir.y * d;
- if( d > 0 && c2 >= box->min.y && c2 <= box->max.y && d <= col_time )
- {
- col_time = d;
- col_normal.set( -1, 0 );
- col = true;
- }
- vec2d col_pt;
- vec2d col_unmax;
- float len_unmax;
- /// Vertex 1
- D = b_p1 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p1 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p1 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p1;
- col_normal.normalize();
- col = true;
- }
- }
- /// Vertex 2 NOT
- /// Vertex 3
- D = b_p3 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p3 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p3 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p3;
- col_normal.normalize();
- col = true;
- }
- }
- /// Vertex 4
- D = b_p4 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p4 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p4 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p4;
- col_normal.normalize();
- col = true;
- }
- }
- /// Long&round side
- /// only square shapes like this supported which are bigger than the radius is..
- /// get l1 - distance from center of circle to the possible collision
- float l1 = box->max.x - box->min.x - g_ball->radius;
- vec2d pos2cnt = b_p2 - g_ball->pos;
- float p2c_length = pos2cnt.length();
- pos2cnt /= p2c_length;
- float angZ = acos( pos2cnt * m_vdir );
- float stp1 = l1 / sin( angZ );
- float angT = asin( p2c_length / stp1 );
- float angX = deg2rad( 180 ) - angZ - angT;
- float l3 = stp1 * sin( angX );
- float time = l3 / v_length;
- col_pt = g_ball->pos + m_vel * time;
- vec2d col_norm = b_p2 - col_pt;
- col_norm.normalize();
- vec2d col_dv( 1, -1 );
- col_dv.normalize();
- if( col_norm * col_dv > cos( deg2rad( 45 ) ) &&
- time >= 0 && time < col_time )
- {
- col_time = time;
- col_normal = col_norm;
- col = true;
- }
- /// Before returning, check the ball
- float axis1 = g_ball->pos.x + g_ball->radius - box->min.x;
- float axis2 = box->max.y + g_ball->radius - g_ball->pos.y;
- float axis3 = p2c_length - l1;
- if( axis1 > 0 && axis1 < l1 + g_ball->radius &&
- axis2 > 0 && axis2 < l1 + g_ball->radius &&
- axis3 > 0.5 && axis3 < l1 )
- {
- int axisnb = 0;
- float axiscmp = axis1;
- if( axis2 < axis1 )
- {
- axisnb = 1;
- axiscmp = axis2;
- }
- if( axis3 < axiscmp ) axisnb = 2;
- if( axisnb == 0 )
- {
- g_ball->pos.x = box->min.x - g_ball->radius;
- g_col_normal.set( -1, 0 );
- return MIN_TIMEPT;
- }
- if( axisnb == 1 )
- {
- g_ball->pos.y = box->max.y + g_ball->radius;
- g_col_normal.set( 0, 1 );
- return MIN_TIMEPT;
- }
- if( axisnb == 2 && col_norm * col_dv > cos( deg2rad( 45 ) ) )
- {
- g_ball->pos = b_p2 - pos2cnt * l1 * GETIN_K;
- g_col_normal = pos2cnt;
- return MIN_TIMEPT;
- }
- }
- if( col == false ) return -1;
- g_col_normal = col_normal;
- return col_time;
- }
- /// Collision function
- /// Ball - Box + circle inside cut ; edges - right/down
- /// Ball can collide with edges and vertices and the slope of the "box"
- float ball_box_collision_trdi( const box_t* box, const vec2d& next_pos, float max_time )
- {
- vec2d m_normal( -g_ball->vel.y, g_ball->vel.x );
- m_normal.normalize();
- float p_mid = m_normal * g_ball->pos;
- float p_min = p_mid - g_ball->radius;
- float p_max = p_mid + g_ball->radius;
- vec2d m_vdir = next_pos - g_ball->pos;
- vec2d m_vel = m_vdir;
- float v_length = m_vdir.length();
- m_vdir /= v_length;
- vec2d b_p1 = box->min;
- vec2d b_p2 = vec2d( box->max.x, box->min.y );
- vec2d b_p3 = box->max;
- vec2d b_p4 = vec2d( box->min.x, box->max.y );
- /// collision data
- vec2d col_normal( 0, 0 );
- float col_time = max_time;
- vec2d D;
- float len, d, c, c2;
- bool col = false;
- /// Edge 1 EMPTY
- /// Edge 2
- c = box->max.x + g_ball->radius;
- d = ( c - g_ball->pos.x ) / ( next_pos.x - g_ball->pos.x );
- c2 = g_ball->pos.y + m_vdir.y * d;
- if( d > 0 && c2 >= box->min.y && c2 <= box->max.y && d <= col_time )
- {
- col_time = d;
- col_normal.set( 1, 0 );
- col = true;
- }
- /// Edge 3
- c = box->max.y + g_ball->radius;
- d = ( c - g_ball->pos.y ) / ( next_pos.y - g_ball->pos.y );
- c2 = g_ball->pos.x + m_vdir.x * d;
- if( d > 0 && c2 >= box->min.x && c2 <= box->max.x && d <= col_time )
- {
- col_time = d;
- col_normal.set( 0, 1 );
- col = true;
- }
- /// Edge 4 EMPTY
- vec2d col_pt;
- vec2d col_unmax;
- float len_unmax;
- /// Vertex 1 NOT
- /// Vertex 2
- D = b_p2 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p2 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p2 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p2;
- col_normal.normalize();
- col = true;
- }
- }
- /// Vertex 3
- D = b_p3 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p3 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p3 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p3;
- col_normal.normalize();
- col = true;
- }
- }
- /// Vertex 4
- D = b_p4 - g_ball->pos;
- d = D * m_vdir;
- d = d >= 0 ? d : 0;
- c = d;
- d = d < v_length ? d : v_length;
- col_pt = g_ball->pos + m_vdir * d;
- col_unmax = g_ball->pos + m_vdir * c;
- len_unmax = ( col_unmax - b_p4 ).length();
- d = ( c - sqrt( g_ball->radius * g_ball->radius - len_unmax * len_unmax ) ) / v_length;
- len = ( b_p4 - col_pt ).length();
- col_pt = g_ball->pos + m_vel * d;
- len -= c - d;
- if( len <= g_ball->radius )
- {
- if( d >= 0 && d < col_time )
- {
- col_time = d;
- col_normal = col_pt - b_p4;
- col_normal.normalize();
- col = true;
- }
- }
- /// Long&round side
- /// only square shapes like this supported which are bigger than the radius is..
- /// get l1 - distance from center of circle to the possible collision
- float l1 = box->max.x - box->min.x - g_ball->radius;
- vec2d pos2cnt = b_p1 - g_ball->pos;
- float p2c_length = pos2cnt.length();
- pos2cnt /= p2c_length;
- float angZ = acos( pos2cnt * m_vdir );
- float stp1 = l1 / sin( angZ );
- float angT = asin( p2c_length / stp1 );
- float angX = deg2rad( 180 ) - angZ - angT;
- float l3 = stp1 * sin( angX );
- float time = l3 / v_length;
- col_pt = g_ball->pos + m_vel * time;
- vec2d col_norm = b_p1 - col_pt;
- col_norm.normalize();
- vec2d col_dv( -1, -1 );
- col_dv.normalize();
- if( col_norm * col_dv > cos( deg2rad( 45 ) ) &&
- time >= 0 && time < col_time )
- {
- col_time = time;
- col_normal = col_norm;
- col = true;
- }
- /// Before returning, check the ball
- float axis1 = box->max.x - g_ball->pos.x - g_ball->radius;
- float axis2 = box->max.y + g_ball->radius - g_ball->pos.y;
- float axis3 = p2c_length - l1;
- if( axis1 > 0 && axis1 < l1 + g_ball->radius &&
- axis2 > 0 && axis2 < l1 + g_ball->radius &&
- axis3 > 0 && axis3 < l1 )
- {
- int axisnb = 0;
- float axiscmp = axis1;
- if( axis2 < axis1 )
- {
- axisnb = 1;
- axiscmp = axis2;
- }
- if( axis3 < axiscmp ) axisnb = 2;
- if( axisnb == 0 )
- {
- g_ball->pos.x = box->max.x + g_ball->radius;
- g_col_normal.set( 1, 0 );
- return MIN_TIMEPT;
- }
- if( axisnb == 1 )
- {
- g_ball->pos.y = box->max.y + g_ball->radius;
- g_col_normal.set( 0, 1 );
- return MIN_TIMEPT;
- }
- if( axisnb == 2 && col_norm * col_dv > cos( deg2rad( 45 ) ) )
- {
- g_ball->pos = b_p1 - pos2cnt * l1 * GETIN_K;
- g_col_normal = pos2cnt;
- return MIN_TIMEPT;
- }
- }
- if( col == false ) return -1;
- g_col_normal = col_normal;
- return col_time;
- }
- void integrate( const float time )
- {
- if( time <= 0 )
- return;
- g_ball->vel += g_ball->acc * time;
- g_ball->angle += g_ball->avel * time;
- vec2d next_pos = g_ball->pos + g_ball->vel * time;
- float best_col_time = 2;
- vec2d best_col_normal;
- float time_left = 1;
- while( time_left > 0 )
- {
- for( int i = 0; i < g_box_count; ++i )
- {
- float time = best_col_time;
- if( g_boxes[ i ].type == TY_SPEC_LD )
- {
- time = ball_box_collision_tldi( &(g_boxes[ i ]), next_pos, time_left );
- }
- else if( g_boxes[ i ].type == TY_SPEC_RD )
- {
- time = ball_box_collision_trdi( &(g_boxes[ i ]), next_pos, time_left );
- }
- else
- {
- time = ball_box_collision_t0( &(g_boxes[ i ]), next_pos, time_left );
- }
- if( time < best_col_time && time > 0 )
- {
- best_col_time = time;
- best_col_normal = g_col_normal;
- }
- }
- time_left -= best_col_time;
- g_ball->pos += g_ball->vel * min( best_col_time, 1.0f ) * time;
- if( best_col_time < 2 )
- {
- vec2d vel_new = g_ball->vel.reflect( best_col_normal );
- vec2d bc_tangent( -best_col_normal.y, best_col_normal.x );
- float vel_n = best_col_normal * vel_new * g_ball->restitution;
- float vel_t = bc_tangent * vel_new * ( 1 - g_ball->friction );//lerp( 1, ( 1 - g_ball->friction ), time * best_col_time );
- //length = 2 * pi * radius * k
- //vel_t = 2 * pi * radius * k
- //k = vel_t / 2 * pi * radius
- g_ball->avel = -vel_t;// / ( 2 * PI * g_ball->radius );
- g_ball->vel = best_col_normal * vel_n + bc_tangent * vel_t;
- next_pos = g_ball->pos + g_ball->vel * time;
- best_col_time = 2;
- }
- }
- }
- void storage_resize( int size )
- {
- box_t* boxes = new box_t[ size ];
- memcpy_s( boxes, size, g_boxes, __real_box_size );
- if( size < g_box_count )
- {
- g_box_count = size;
- }
- __real_box_size = size;
- delete [] g_boxes;
- g_boxes = boxes;
- }
- ///////
- ///// THE
- ///// PHYSICS
- ///// ENGINE
- ///////
- #define DLL_EXP extern "C" __declspec(dllexport)
- #define BALL_SET( what, varname, argname ) \
- DLL_EXP double phy_ball_##what##_set( double argname ) \
- { \
- g_ball->##varname = (float) argname; \
- return 0; \
- }
- #define BALL_SETVEC( what, varname1, varname2, argname1, argname2 ) \
- DLL_EXP double phy_ball_##what##_set( double argname1, double argname2 ) \
- { \
- g_ball->##varname1 = (float) argname1; \
- g_ball->##varname2 = (float) argname2; \
- return 0; \
- }
- #define BALL_GET( what, varname ) \
- DLL_EXP double phy_ball_##what##_get() \
- { \
- return (float) g_ball->##varname; \
- }
- bool g_initialized = false;
- DLL_EXP double phy_start()
- {
- g_boxes = new box_t[ 1000 ];
- __real_box_size = 1000;
- g_ball = new ball_t;
- memset( g_ball, 0, sizeof(ball_t) );
- g_initialized = true;
- return 0;
- }
- DLL_EXP double phy_end()
- {
- delete [] g_boxes;
- g_initialized = false;
- return 0;
- }
- DLL_EXP double phy_step( double time )
- {
- integrate( (float) time );
- return 0;
- }
- DLL_EXP double phy_box_add( double x1, double x2, double y1, double y2, double type )
- {
- if( g_box_count == __real_box_size )
- {
- storage_resize( __real_box_size * 2 );
- }
- g_boxes[ g_box_count ].min.set( (float) x1, (float) y1 );
- g_boxes[ g_box_count ].max.set( (float) x2, (float) y2 );
- g_boxes[ g_box_count ].type = (int) type;
- g_box_count++;
- return 0;
- }
- DLL_EXP double phy_box_clear()
- {
- g_box_count = 0;
- return 0;
- }
- BALL_SET(friction,friction,friction)
- BALL_SET(restitution,restitution,restitution)
- BALL_SET(radius,radius,radius)
- BALL_SET(avel,avel,avel)
- BALL_SET(angle,angle,angle)
- BALL_SET(x,pos.x,x)
- BALL_SET(y,pos.y,y)
- BALL_SET(vel_x,vel.x,x)
- BALL_SET(vel_y,vel.y,y)
- BALL_SET(acc_x,acc.x,x)
- BALL_SET(acc_y,acc.y,y)
- BALL_SETVEC(pos,pos.x,pos.y,x,y);
- BALL_SETVEC(vel,vel.x,vel.y,x,y);
- BALL_SETVEC(acc,acc.x,acc.y,x,y);
- BALL_GET(friction,friction)
- BALL_GET(restitution,restitution)
- BALL_GET(radius,radius)
- BALL_GET(avel,avel)
- BALL_GET(angle,angle)
- BALL_GET(x,pos.x)
- BALL_GET(y,pos.y)
- BALL_GET(vel_x,vel.x)
- BALL_GET(vel_y,vel.y)
- BALL_GET(acc_x,acc.x)
- BALL_GET(acc_y,acc.y)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement