//collision move cylinder to static cylinder bool kgmCollision::collision(vec3& start, vec3& end, kgmCylinder3d<float>& cyl, kgmCylinder3d<float>& scyl, vec3& rpt) { kgmLine3d<float> line(start, end); vec3 pt_proj; vec3 pt_temp; float dist_start_proj; float dist_scyl_proj; pt_proj = line.projection(scyl.position); dist_start_proj = start.distance(pt_proj); if(dist_start_proj > (start.distance(end) + cyl.radius)) return false; pt_temp = vec3(pt_proj.x, pt_proj.y, scyl.position.z); dist_scyl_proj = pt_temp.distance(scyl.position); if(dist_scyl_proj > (cyl.radius + scyl.radius)) return false; if((pt_proj.z < (scyl.position.z - cyl.height)) || (pt_proj.z > (scyl.position.z + scyl.height))) return false; rpt = pt_proj; return true; }
//collision move box to static box bool kgmCollision::collision(vec3& start, vec3& end, kgmBox3d<float>& mbox, kgmBox3d<float>& sbox, vec3& rpt) { kgmLine3d<float> line(start, end); vec3 pt_proj; vec3 pt_temp; float dist_proj; float dist_sbox_proj; vec3 pt_mbox = (mbox.min + mbox.max) * 0.5f; pt_mbox.z = mbox.min.z; vec3 pr_mbox = mbox.max - mbox.min; vec3 pt_sbox = (sbox.min + sbox.max) * 0.5f; pt_sbox.z = sbox.min.z; vec3 pr_sbox = sbox.max - sbox.min; pt_proj = line.projection(pt_sbox); dist_proj = start.distance(pt_proj); if(dist_proj > (start.distance(end))) return false; pt_temp = vec3(pt_proj.x, pt_proj.y, pt_sbox.z); if((fabs(pt_temp.x - pt_sbox.x)) > (pr_sbox.x * 0.5f + pr_mbox.x * 0.5f)) return false; if((fabs(pt_temp.y - pt_sbox.y)) > (pr_sbox.y * 0.5f + pr_mbox.y * 0.5f)) return false; if((pt_proj.z < (pt_sbox.z - pr_mbox.z)) || (pt_proj.z > (pt_sbox.z + pr_sbox.z))) return false; rpt = pt_proj; return true; }
//-------------------------------------------------------------------------------- // get pitch by eye for follow mode //-------------------------------------------------------------------------------- float zz_camera_follow::get_pitch_by_eye (const vec3& eye_pos) { // [MIN_PITCH_RADIAN, MIN_PITCH_RADIAN + PITCH_RADIAN_RANGE] vec3 eye_pos_z = eye_pos; eye_pos_z.z = final_.target_pos.z; // projected eye on the [target_pos.z] plane. float pitch_angle; // in radian pitch_angle = cosf(eye_pos_z.distance(final_.target_pos) / eye_pos.distance(final_.target_pos)); if (eye_pos.z < eye_pos_z.z) { // invert angle pitch_angle = -pitch_angle; } float new_pitch = (pitch_angle - MIN_PITCH_RADIAN) / PITCH_RADIAN_RANGE; return new_pitch; }
//collision move sphere with box bool kgmCollision::collision(vec3& start, vec3& end, float radius, box& b, mtx4& btr) { int i = 0; vec3 box_points[8]; vec3 box_sides[6][4]; b.points(box_points); for(i = 0; i < 8; i++) box_points[i] = btr * box_points[i]; box_sides[0][0] = box_points[0]; box_sides[0][1] = box_points[1]; box_sides[0][2] = box_points[5]; box_sides[0][3] = box_points[4]; box_sides[1][0] = box_points[1]; box_sides[1][1] = box_points[3]; box_sides[1][2] = box_points[7]; box_sides[1][3] = box_points[5]; box_sides[2][0] = box_points[3]; box_sides[2][1] = box_points[2]; box_sides[2][2] = box_points[6]; box_sides[2][3] = box_points[7]; box_sides[3][0] = box_points[2]; box_sides[3][1] = box_points[0]; box_sides[3][2] = box_points[4]; box_sides[3][3] = box_points[6]; box_sides[4][0] = box_points[0]; box_sides[4][1] = box_points[2]; box_sides[4][2] = box_points[3]; box_sides[4][3] = box_points[1]; box_sides[5][0] = box_points[4]; box_sides[5][1] = box_points[5]; box_sides[5][2] = box_points[7]; box_sides[5][3] = box_points[6]; float dist = -1.0f; vec3 ptins; m_collision = false; for(i = 0; i < 6; i++) { if(collision(start, end, radius, box_sides[i], 4)) { // if(collision(start, end, radius, box_sides[i][0], box_sides[i][1],box_sides[i][2], ptins) || // collision(start, end, radius, box_sides[i][0], box_sides[i][2],box_sides[i][3], ptins)){ ptins = m_point; m_collision = true; break; if(m_collision) { if(start.distance(m_point) > dist) m_point = ptins; else dist = start.distance(m_point); } else { dist = start.distance(m_point); } m_collision = true; } } return m_collision; }
//-------------------------------------------------------------------------------- // get distance by eye for follow mode //-------------------------------------------------------------------------------- float zz_camera_follow::get_distance_by_eye (const vec3& eye_pos) { // assumes target_pos already be set return eye_pos.distance(final_.target_pos); }