void LineSegSlingshot::Collide(CollisionEvent* coll) { Ball *pball = coll->ball; const Vertex3Ds& hitnormal = coll->hitnormal; const float dot = pball->m_vel.x * hitnormal.x + pball->m_vel.y * hitnormal.y; // normal velocity to slingshot const bool threshold = (dot <= -m_psurface->m_d.m_slingshot_threshold); // normal greater than threshold? if (!m_psurface->m_fDisabled && threshold) // enabled and if velocity greater than threshold level { const float len = (v2.x - v1.x)*hitnormal.y - (v2.y - v1.y)*hitnormal.x; // length of segment, Unit TAN points from V1 to V2 const Vertex2D vhitpoint(pball->m_pos.x - hitnormal.x * pball->m_radius, //project ball radius along norm pball->m_pos.y - hitnormal.y * pball->m_radius); // vhitpoint will now be the point where the ball hits the line // Calculate this distance from the center of the slingshot to get force const float btd = (vhitpoint.x - v1.x)*hitnormal.y - (vhitpoint.y - v1.y)*hitnormal.x; // distance to vhit from V1 float force = (len != 0.0f) ? ((btd+btd)/len - 1.0f) : -1.0f; // -1..+1 force = 0.5f *(1.0f-force*force); //!! maximum value 0.5 ...I think this should have been 1.0...oh well // will match the previous physics force *= m_force;//-80; pball->m_vel.x -= hitnormal.x * force; // boost velocity, drive into slingshot (counter normal) pball->m_vel.y -= hitnormal.y * force; // allow CollideWall to handle the remainder } pball->Collide2DWall(hitnormal, m_elasticity, m_elasticityFalloff, m_friction, m_scatter); if (m_pfe && !m_psurface->m_fDisabled && threshold) { // is this the same place as last event? if same then ignore it const Vertex3Ds dist = pball->m_Event_Pos - pball->m_pos; pball->m_Event_Pos = pball->m_pos; //remember last collide position if (dist.LengthSquared() > 0.25f) // must be a new place if only by a little { m_pfe->FireGroupEvent(DISPID_SurfaceEvents_Slingshot); m_slingshotanim.m_TimeReset = g_pplayer->m_time_msec + 100; } } }
void BumperHitCircle::Collide(CollisionEvent* coll) { Ball *pball = coll->ball; const Vertex3Ds& hitnormal = coll->hitnormal; const float dot = hitnormal.x * pball->m_vel.x + hitnormal.y * pball->m_vel.y; pball->Collide2DWall(hitnormal, m_elasticity, m_elasticityFalloff, m_friction, m_scatter); //reflect ball from wall // if the bumper is disabled then don't activate the bumper if (m_pbumper->m_fDisabled) return; if (dot <= -m_pbumper->m_d.m_threshold) // if velocity greater than threshold level { pball->m_vel.x += hitnormal.x * m_pbumper->m_d.m_force; // add a chunk of velocity to drive ball away pball->m_vel.y += hitnormal.y * m_pbumper->m_d.m_force; m_bumperanim.m_fHitEvent = true; m_pbumper->FireGroupEvent(DISPID_HitEvents_Hit); } }