2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*  geometry.h                                                           */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                       This file is part of:                           */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                           GODOT ENGINE                                */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                    http://www.godotengine.org                         */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
									
										
										
										
											2017-01-01 22:01:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*                                                                       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Permission is hereby granted, free of charge, to any person obtaining */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* a copy of this software and associated documentation files (the       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* "Software"), to deal in the Software without restriction, including   */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* without limitation the rights to use, copy, modify, merge, publish,   */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* distribute, sublicense, and/or sell copies of the Software, and to    */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* permit persons to whom the Software is furnished to do so, subject to */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* the following conditions:                                             */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* The above copyright notice and this permission notice shall be        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* included in all copies or substantial portions of the Software.       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef GEOMETRY_H 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define GEOMETRY_H 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "dvector.h" 
  
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "face3.h" 
  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "math_2d.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "object.h" 
  
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "print_string.h" 
  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "triangulate.h" 
  
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "vector.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "vector3.h" 
  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									@ author  Juan  Linietsky  < reduzio @ gmail . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  Geometry  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Geometry ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  real_t  get_closest_points_between_segments ( const  Vector2  & p1 ,  const  Vector2  & q1 ,  const  Vector2  & p2 ,  const  Vector2  & q2 ,  Vector2  & c1 ,  Vector2  & c2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector2  d1  =  q1  -  p1 ;  // Direction vector of segment S1
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector2  d2  =  q2  -  p2 ;  // Direction vector of segment S2
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector2  r  =  p1  -  p2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  a  =  d1 . dot ( d1 ) ;  // Squared length of segment S1, always nonnegative
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  e  =  d2 . dot ( d2 ) ;  // Squared length of segment S2, always nonnegative
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  f  =  d2 . dot ( r ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  s ,  t ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// Check if either or both segments degenerate into points
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( a  < =  CMP_EPSILON  & &  e  < =  CMP_EPSILON )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Both segments degenerate into points
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c1  =  p1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c2  =  p2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  Math : : sqrt ( ( c1  -  c2 ) . dot ( c1  -  c2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( a  < =  CMP_EPSILON )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// First segment degenerates into a point
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											s  =  0.0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											t  =  f  /  e ;  // s = 0 => t = (b*s + f) / e = f / e
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t  =  CLAMP ( t ,  0.0 ,  1.0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											real_t  c  =  d1 . dot ( r ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( e  < =  CMP_EPSILON )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Second segment degenerates into a point
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t  =  0.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s  =  CLAMP ( - c  /  a ,  0.0 ,  1.0 ) ;  // t = 0 => s = (b*t - c) / a = -c / a
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// The general nondegenerate case starts here
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												real_t  b  =  d1 . dot ( d2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												real_t  denom  =  a  *  e  -  b  *  b ;  // Always nonnegative
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												// If segments not parallel, compute closest point on L1 to L2 and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// clamp to segment S1. Else pick arbitrary s (here 0)
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( denom  ! =  0.0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													s  =  CLAMP ( ( b  *  f  -  c  *  e )  /  denom ,  0.0 ,  1.0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													s  =  0.0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												// Compute point on L2 closest to S1(s) using
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// t = Dot((P1 + D1*s) - P2,D2) / Dot(D2,D2) = (b*s + f) / e
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t  =  ( b  *  s  +  f )  /  e ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//If t in [0,1] done. Else clamp t, recompute s for the new value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// of t using s = Dot((P2 + D2*t) - P1,D1) / Dot(D1,D1)= (t*b - c) / a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// and clamp s to [0, 1]
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( t  <  0.0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													t  =  0.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													s  =  CLAMP ( - c  /  a ,  0.0 ,  1.0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( t  >  1.0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													t  =  1.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													s  =  CLAMP ( ( b  -  c )  /  a ,  0.0 ,  1.0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c1  =  p1  +  d1  *  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c2  =  p2  +  d2  *  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Math : : sqrt ( ( c1  -  c2 ) . dot ( c1  -  c2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  void  get_closest_points_between_segments ( const  Vector3  & p1 ,  const  Vector3  & p2 ,  const  Vector3  & q1 ,  const  Vector3  & q2 ,  Vector3  & c1 ,  Vector3  & c2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-15 08:29:46 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								#if 0 
  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										//do the function 'd' as defined by pb. I think is is dot product of some sort
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define d_of(m, n, o, p) ((m.x - n.x) * (o.x - p.x) + (m.y - n.y) * (o.y - p.y) + (m.z - n.z) * (o.z - p.z)) 
  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-24 21:45:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//calculate the parametric position on the 2 curves, mua and mub
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  mua  =  (  d_of ( p1 , q1 , q2 , q1 )  *  d_of ( q2 , q1 , p2 , p1 )   -  d_of ( p1 , q1 , p2 , p1 )  *  d_of ( q2 , q1 , q2 , q1 )  )  /  (  d_of ( p2 , p1 , p2 , p1 )  *  d_of ( q2 , q1 , q2 , q1 )   -  d_of ( q2 , q1 , p2 , p1 )  *  d_of ( q2 , q1 , p2 , p1 )  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  mub  =  (  d_of ( p1 , q1 , q2 , q1 )  +  mua  *  d_of ( q2 , q1 , p2 , p1 )   )  /  d_of ( q2 , q1 , q2 , q1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//clip the value between [0..1] constraining the solution to lie on the original curves
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( mua  <  0 )  mua  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( mub  <  0 )  mub  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( mua  >  1 )  mua  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( mub  >  1 )  mub  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c1  =  p1 . linear_interpolate ( p2 , mua ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c2  =  q1 . linear_interpolate ( q2 , mub ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-15 08:29:46 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  u  =  p2  -  p1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  v  =  q2  -  q1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  w  =  p1  -  q1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										float  a  =  u . dot ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										float  b  =  u . dot ( v ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										float  c  =  v . dot ( v ) ;  // always >= 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										float  d  =  u . dot ( w ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										float  e  =  v . dot ( w ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										float  D  =  a  *  c  -  b  *  b ;  // always >= 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										float  sc ,  tc ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-15 08:29:46 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// compute the line parameters of the two closest points
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( D  <  CMP_EPSILON )  {  // the lines are almost parallel
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-15 08:29:46 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											sc  =  0.0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											tc  =  ( b  >  c  ?  d  /  b  :  e  /  c ) ;  // use the largest denominator
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sc  =  ( b  *  e  -  c  *  d )  /  D ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tc  =  ( a  *  e  -  b  *  d )  /  D ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-15 08:29:46 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c1  =  w  +  sc  *  u ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c2  =  w  +  tc  *  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// get the difference of the two closest points
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//Vector   dP = w + (sc * u) - (tc * v);  // =  L1(sc) - L2(tc)
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  real_t  get_closest_distance_between_segments ( const  Vector3  & p_from_a ,  const  Vector3  & p_to_a ,  const  Vector3  & p_from_b ,  const  Vector3  & p_to_b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  u  =  p_to_a  -  p_from_a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  v  =  p_to_b  -  p_from_b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  w  =  p_from_a  -  p_to_a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  a  =  u . dot ( u ) ;  // always >= 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  b  =  u . dot ( v ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  c  =  v . dot ( v ) ;  // always >= 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  d  =  u . dot ( w ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  e  =  v . dot ( w ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  D  =  a  *  c  -  b  *  b ;  // always >= 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  sc ,  sN ,  sD  =  D ;  // sc = sN / sD, default sD = D >= 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  tc ,  tN ,  tD  =  D ;  // tc = tN / tD, default tD = D >= 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// compute the line parameters of the two closest points
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( D  <  CMP_EPSILON )  {  // the lines are almost parallel
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sN  =  0.0 ;  // force using point P0 on segment S1
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sD  =  1.0 ;  // to prevent possible division by 0.0 later
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tN  =  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tD  =  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  {  // get the closest points on the infinite lines
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sN  =  ( b  *  e  -  c  *  d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tN  =  ( a  *  e  -  b  *  d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( sN  <  0.0 )  {  // sc < 0 => the s=0 edge is visible
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sN  =  0.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tN  =  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tD  =  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( sN  >  sD )  {  // sc > 1 => the s=1 edge is visible
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sN  =  sD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tN  =  e  +  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tD  =  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( tN  <  0.0 )  {  // tc < 0 => the t=0 edge is visible
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tN  =  0.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// recompute sc for this edge
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( - d  <  0.0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sN  =  0.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else  if  ( - d  >  a ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sN  =  sD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sN  =  - d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sD  =  a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( tN  >  tD )  {  // tc > 1 => the t=1 edge is visible
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tN  =  tD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// recompute sc for this edge
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( - d  +  b )  <  0.0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sN  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else  if  ( ( - d  +  b )  >  a ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sN  =  sD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sN  =  ( - d  +  b ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sD  =  a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// finally do the division to get sc and tc
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sc  =  ( Math : : abs ( sN )  <  CMP_EPSILON  ?  0.0  :  sN  /  sD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tc  =  ( Math : : abs ( tN )  <  CMP_EPSILON  ?  0.0  :  tN  /  tD ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// get the difference of the two closest points
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  dP  =  w  +  ( sc  *  u )  -  ( tc  *  v ) ;  // = S1(sc) - S2(tc)
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  dP . length ( ) ;  // return the closest distance
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  inline  bool  ray_intersects_triangle ( const  Vector3  & p_from ,  const  Vector3  & p_dir ,  const  Vector3  & p_v0 ,  const  Vector3  & p_v1 ,  const  Vector3  & p_v2 ,  Vector3  * r_res  =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  e1  =  p_v1  -  p_v0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  e2  =  p_v2  -  p_v0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										Vector3  h  =  p_dir . cross ( e2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  a  =  e1 . dot ( h ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( a  >  - CMP_EPSILON  & &  a  <  CMP_EPSILON )  // parallel test
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  f  =  1.0  /  a ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  s  =  p_from  -  p_v0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										real_t  u  =  f  *  s . dot ( h ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( u  <  0.0  | |  u  >  1.0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  q  =  s . cross ( e1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										real_t  v  =  f  *  p_dir . dot ( q ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( v  <  0.0  | |  u  +  v  >  1.0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// at this stage we can compute t to find out where
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// the intersection point is on the line
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  t  =  f  *  e2 . dot ( q ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( t  >  0.00001 )  {  // ray intersection
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( r_res ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												* r_res  =  p_from  +  p_dir  *  t ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  // this means that there is a line intersection
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											// but not a ray intersection
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  inline  bool  segment_intersects_triangle ( const  Vector3  & p_from ,  const  Vector3  & p_to ,  const  Vector3  & p_v0 ,  const  Vector3  & p_v1 ,  const  Vector3  & p_v2 ,  Vector3  * r_res  =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  rel  =  p_to  -  p_from ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  e1  =  p_v1  -  p_v0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  e2  =  p_v2  -  p_v0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										Vector3  h  =  rel . cross ( e2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  a  =  e1 . dot ( h ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( a  >  - CMP_EPSILON  & &  a  <  CMP_EPSILON )  // parallel test
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  f  =  1.0  /  a ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  s  =  p_from  -  p_v0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										real_t  u  =  f  *  s . dot ( h ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( u  <  0.0  | |  u  >  1.0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  q  =  s . cross ( e1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										real_t  v  =  f  *  rel . dot ( q ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( v  <  0.0  | |  u  +  v  >  1.0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// at this stage we can compute t to find out where
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// the intersection point is on the line
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  t  =  f  *  e2 . dot ( q ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( t  >  CMP_EPSILON  & &  t  < =  1.0 )  {  // ray intersection
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( r_res ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												* r_res  =  p_from  +  rel  *  t ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  // this means that there is a line intersection
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											// but not a ray intersection
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  inline  bool  segment_intersects_sphere ( const  Vector3  & p_from ,  const  Vector3  & p_to ,  const  Vector3  & p_sphere_pos ,  real_t  p_sphere_radius ,  Vector3  * r_res  =  0 ,  Vector3  * r_norm  =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  sphere_pos  =  p_sphere_pos  -  p_from ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  rel  =  ( p_to  -  p_from ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  rel_l  =  rel . length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rel_l  <  CMP_EPSILON ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ;  // both points are the same
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  normal  =  rel  /  rel_l ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  sphere_d  =  normal . dot ( sphere_pos ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//Vector3 ray_closest=normal*sphere_d;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  ray_distance  =  sphere_pos . distance_to ( normal  *  sphere_d ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ray_distance  > =  p_sphere_radius ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  inters_d2  =  p_sphere_radius  *  p_sphere_radius  -  ray_distance  *  ray_distance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  inters_d  =  sphere_d ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( inters_d2  > =  CMP_EPSILON ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											inters_d  - =  Math : : sqrt ( inters_d2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// check in segment
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( inters_d  <  0  | |  inters_d  >  rel_l ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  result  =  p_from  +  normal  *  inters_d ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( r_res ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											* r_res  =  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( r_norm ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											* r_norm  =  ( result  -  p_sphere_pos ) . normalized ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  inline  bool  segment_intersects_cylinder ( const  Vector3  & p_from ,  const  Vector3  & p_to ,  real_t  p_height ,  real_t  p_radius ,  Vector3  * r_res  =  0 ,  Vector3  * r_norm  =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  rel  =  ( p_to  -  p_from ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  rel_l  =  rel . length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rel_l  <  CMP_EPSILON ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ;  // both points are the same
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// first check if they are parallel
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  normal  =  ( rel  /  rel_l ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  crs  =  normal . cross ( Vector3 ( 0 ,  0 ,  1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  crs_l  =  crs . length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  z_dir ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( crs_l  <  CMP_EPSILON )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											//blahblah parallel
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											z_dir  =  Vector3 ( 1 ,  0 ,  0 ) ;  //any x/y vector ok
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											z_dir  =  crs  /  crs_l ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  dist  =  z_dir . dot ( p_from ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( dist  > =  p_radius ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ;  // too far away
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// convert to 2D
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  w2  =  p_radius  *  p_radius  -  dist  *  dist ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( w2  <  CMP_EPSILON ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ;  //avoid numerical error
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Size2  size ( Math : : sqrt ( w2 ) ,  p_height  *  0.5 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  x_dir  =  z_dir . cross ( Vector3 ( 0 ,  0 ,  1 ) ) . normalized ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector2  from2D ( x_dir . dot ( p_from ) ,  p_from . z ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector2  to2D ( x_dir . dot ( p_to ) ,  p_to . z ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  min  =  0 ,  max  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  axis  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( int  i  =  0 ;  i  <  2 ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											real_t  seg_from  =  from2D [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											real_t  seg_to  =  to2D [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											real_t  box_begin  =  - size [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											real_t  box_end  =  size [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											real_t  cmin ,  cmax ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( seg_from  <  seg_to )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( seg_from  >  box_end  | |  seg_to  <  box_begin ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												real_t  length  =  seg_to  -  seg_from ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cmin  =  ( seg_from  <  box_begin )  ?  ( ( box_begin  -  seg_from )  /  length )  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cmax  =  ( seg_to  >  box_end )  ?  ( ( box_end  -  seg_from )  /  length )  :  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( seg_to  >  box_end  | |  seg_from  <  box_begin ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												real_t  length  =  seg_to  -  seg_from ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cmin  =  ( seg_from  >  box_end )  ?  ( box_end  -  seg_from )  /  length  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cmax  =  ( seg_to  <  box_begin )  ?  ( box_begin  -  seg_from )  /  length  :  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( cmin  >  min )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												min  =  cmin ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												axis  =  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( cmax  <  max ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												max  =  cmax ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( max  <  min ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// convert to 3D again
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  result  =  p_from  +  ( rel  *  min ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										Vector3  res_normal  =  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( axis  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res_normal . z  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res_normal . x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res_normal . y  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res_normal . normalize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( r_res ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											* r_res  =  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( r_norm ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											* r_norm  =  res_normal ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  bool  segment_intersects_convex ( const  Vector3  & p_from ,  const  Vector3  & p_to ,  const  Plane  * p_planes ,  int  p_plane_count ,  Vector3  * p_res ,  Vector3  * p_norm )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  min  =  - 1e20 ,  max  =  1e20 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  rel  =  p_to  -  p_from ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  rel_l  =  rel . length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( rel_l  <  CMP_EPSILON ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  dir  =  rel  /  rel_l ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  min_index  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( int  i  =  0 ;  i  <  p_plane_count ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  Plane  & p  =  p_planes [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											real_t  den  =  p . normal . dot ( dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											//printf("den is %i\n",den);
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( Math : : abs ( den )  < =  CMP_EPSILON ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												continue ;  // ignore parallel plane
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											real_t  dist  =  - p . distance_to ( p_from )  /  den ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( den  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												//backwards facing plane
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( dist  <  max ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													max  =  dist ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//front facing plane
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( dist  >  min )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													min  =  dist ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													min_index  =  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( max  < =  min  | |  min  <  0  | |  min  >  rel_l  | |  min_index  = =  - 1 )  // exit conditions
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ;  // no intersection
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_res ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											* p_res  =  p_from  +  dir  *  min ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( p_norm ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											* p_norm  =  p_planes [ min_index ] . normal ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  Vector3  get_closest_point_to_segment ( const  Vector3  & p_point ,  const  Vector3  * p_segment )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  p  =  p_point  -  p_segment [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  n  =  p_segment [ 1 ]  -  p_segment [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  l  =  n . length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( l  <  1e-10 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  p_segment [ 0 ] ;  // both points are the same, just give any
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										n  / =  l ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  d  =  n . dot ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( d  < =  0.0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  p_segment [ 0 ] ;  // before first point
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  if  ( d  > =  l ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  p_segment [ 1 ] ;  // after first point
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  p_segment [ 0 ]  +  n  *  d ;  // inside
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  Vector3  get_closest_point_to_segment_uncapped ( const  Vector3  & p_point ,  const  Vector3  * p_segment )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  p  =  p_point  -  p_segment [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector3  n  =  p_segment [ 1 ]  -  p_segment [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  l  =  n . length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( l  <  1e-10 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  p_segment [ 0 ] ;  // both points are the same, just give any
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										n  / =  l ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  d  =  n . dot ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  p_segment [ 0 ]  +  n  *  d ;  // inside
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  Vector2  get_closest_point_to_segment_2d ( const  Vector2  & p_point ,  const  Vector2  * p_segment )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector2  p  =  p_point  -  p_segment [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector2  n  =  p_segment [ 1 ]  -  p_segment [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  l  =  n . length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( l  <  1e-10 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  p_segment [ 0 ] ;  // both points are the same, just give any
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										n  / =  l ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  d  =  n . dot ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( d  < =  0.0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  p_segment [ 0 ] ;  // before first point
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  if  ( d  > =  l ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  p_segment [ 1 ] ;  // after first point
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  p_segment [ 0 ]  +  n  *  d ;  // inside
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-14 12:09:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  bool  is_point_in_triangle ( const  Vector2  & s ,  const  Vector2  & a ,  const  Vector2  & b ,  const  Vector2  & c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  as_x  =  s . x  -  a . x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  as_y  =  s . y  -  a . y ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-14 12:09:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bool  s_ab  =  ( b . x  -  a . x )  *  as_y  -  ( b . y  -  a . y )  *  as_x  >  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-14 12:09:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( ( c . x  -  a . x )  *  as_y  -  ( c . y  -  a . y )  *  as_x  >  0 )  = =  s_ab )  return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-14 12:09:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( ( c . x  -  b . x )  *  ( s . y  -  b . y )  -  ( c . y  -  b . y )  *  ( s . x  -  b . x )  >  0 )  ! =  s_ab )  return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-14 12:09:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-14 12:09:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  Vector2  get_closest_point_to_segment_uncapped_2d ( const  Vector2  & p_point ,  const  Vector2  * p_segment )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector2  p  =  p_point  -  p_segment [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector2  n  =  p_segment [ 1 ]  -  p_segment [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  l  =  n . length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( l  <  1e-10 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  p_segment [ 0 ] ;  // both points are the same, just give any
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										n  / =  l ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  d  =  n . dot ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  p_segment [ 0 ]  +  n  *  d ;  // inside
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  bool  segment_intersects_segment_2d ( const  Vector2  & p_from_a ,  const  Vector2  & p_to_a ,  const  Vector2  & p_from_b ,  const  Vector2  & p_to_b ,  Vector2  * r_result )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector2  B  =  p_to_a  -  p_from_a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector2  C  =  p_from_b  -  p_from_a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector2  D  =  p_to_b  -  p_from_a ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  ABlen  =  B . dot ( B ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ABlen  < =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector2  Bn  =  B  /  ABlen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										C  =  Vector2 ( C . x  *  Bn . x  +  C . y  *  Bn . y ,  C . y  *  Bn . x  -  C . x  *  Bn . y ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										D  =  Vector2 ( D . x  *  Bn . x  +  D . y  *  Bn . y ,  D . y  *  Bn . x  -  D . x  *  Bn . y ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( C . y  <  0  & &  D . y  <  0 )  | |  ( C . y  > =  0  & &  D . y  > =  0 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  ABpos  =  D . x  +  ( C . x  -  D . x )  *  D . y  /  ( D . y  -  C . y ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//  Fail if segment C-D crosses line A-B outside of segment A-B.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ABpos  <  0  | |  ABpos  >  1.0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//  (4) Apply the discovered position to line A-B in the original coordinate system.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( r_result ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											* r_result  =  p_from_a  +  B  *  ABpos ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  inline  bool  point_in_projected_triangle ( const  Vector3  & p_point ,  const  Vector3  & p_v1 ,  const  Vector3  & p_v2 ,  const  Vector3  & p_v3 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  face_n  =  ( p_v1  -  p_v3 ) . cross ( p_v1  -  p_v2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  n1  =  ( p_point  -  p_v3 ) . cross ( p_point  -  p_v2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( face_n . dot ( n1 )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  n2  =  ( p_v1  -  p_v3 ) . cross ( p_v1  -  p_point ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( face_n . dot ( n2 )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  n3  =  ( p_v1  -  p_point ) . cross ( p_v1  -  p_v2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( face_n . dot ( n3 )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  inline  bool  triangle_sphere_intersection_test ( const  Vector3  * p_triangle ,  const  Vector3  & p_normal ,  const  Vector3  & p_sphere_pos ,  real_t  p_sphere_radius ,  Vector3  & r_triangle_contact ,  Vector3  & r_sphere_contact )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										real_t  d  =  p_normal . dot ( p_sphere_pos )  -  p_normal . dot ( p_triangle [ 0 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( d  >  p_sphere_radius  | |  d  <  - p_sphere_radius )  // not touching the plane of the face, return
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector3  contact  =  p_sphere_pos  -  ( p_normal  *  d ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/** 2nd) TEST INSIDE TRIANGLE **/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( Geometry : : point_in_projected_triangle ( contact ,  p_triangle [ 0 ] ,  p_triangle [ 1 ] ,  p_triangle [ 2 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_triangle_contact  =  contact ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r_sphere_contact  =  p_sphere_pos  -  p_normal  *  p_sphere_radius ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											//printf("solved inside triangle\n");
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/** 3rd TEST INSIDE EDGE CYLINDERS **/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  Vector3  verts [ 4 ]  =  {  p_triangle [ 0 ] ,  p_triangle [ 1 ] ,  p_triangle [ 2 ] ,  p_triangle [ 0 ]  } ;  // for() friendly
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( int  i  =  0 ;  i  <  3 ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// check edge cylinder
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Vector3  n1  =  verts [ i ]  -  verts [ i  +  1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector3  n2  =  p_sphere_pos  -  verts [ i  +  1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											///@TODO i could discard by range here to make the algorithm quicker? dunno..
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// check point within cylinder radius
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Vector3  axis  =  n1 . cross ( n2 ) . cross ( n1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											axis . normalize ( ) ;  // ugh
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											real_t  ad  =  axis . dot ( n2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ABS ( ad )  >  p_sphere_radius )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												// no chance with this edge, too far away
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// check point within edge capsule cylinder
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/** 4th TEST INSIDE EDGE POINTS **/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											real_t  sphere_at  =  n1 . dot ( n2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( sphere_at  > =  0  & &  sphere_at  <  n1 . dot ( n1 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_triangle_contact  =  p_sphere_pos  -  axis  *  ( axis . dot ( n2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_sphere_contact  =  p_sphere_pos  -  axis  *  p_sphere_radius ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												// point inside here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//printf("solved inside edge\n");
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											real_t  r2  =  p_sphere_radius  *  p_sphere_radius ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( n2 . length_squared ( )  <  r2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Vector3  n  =  ( p_sphere_pos  -  verts [ i  +  1 ] ) . normalized ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//r_triangle_contact=verts[i+1]+n*p_sphere_radius;p_sphere_pos+axis*(p_sphere_radius-axis.dot(n2));
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_triangle_contact  =  verts [ i  +  1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_sphere_contact  =  p_sphere_pos  -  n  *  p_sphere_radius ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												//printf("solved inside point segment 1\n");
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( n2 . distance_squared_to ( n1 )  <  r2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Vector3  n  =  ( p_sphere_pos  -  verts [ i ] ) . normalized ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												//r_triangle_contact=verts[i]+n*p_sphere_radius;p_sphere_pos+axis*(p_sphere_radius-axis.dot(n2));
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												r_triangle_contact  =  verts [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r_sphere_contact  =  p_sphere_pos  -  n  *  p_sphere_radius ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												//printf("solved inside point segment 1\n");
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ;  // It's pointless to continue at this point, so save some cpu cycles
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  real_t  segment_intersects_circle ( const  Vector2  & p_from ,  const  Vector2  & p_to ,  const  Vector2  & p_circle_pos ,  real_t  p_circle_radius )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector2  line_vec  =  p_to  -  p_from ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector2  vec_to_line  =  p_from  -  p_circle_pos ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* create a quadratic formula of the form ax^2 + bx + c = 0 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  a ,  b ,  c ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										a  =  line_vec . dot ( line_vec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										b  =  2  *  vec_to_line . dot ( line_vec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c  =  vec_to_line . dot ( vec_to_line )  -  p_circle_radius  *  p_circle_radius ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* solve for t */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  sqrtterm  =  b  *  b  -  4  *  a  *  c ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* if the term we intend to square root is less than 0 then the answer won't be real, so it definitely won't be t in the range 0 to 1 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( sqrtterm  <  0 )  return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* if we can assume that the line segment starts outside the circle (e.g. for continuous time collision detection) then the following can be skipped and we can just return the equivalent of res1 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqrtterm  =  Math : : sqrt ( sqrtterm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										real_t  res1  =  ( - b  -  sqrtterm )  /  ( 2  *  a ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										//real_t res2 = ( -b + sqrtterm ) / (2 * a);
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  ( res1  > =  0  & &  res1  < =  1 )  ?  res1  :  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  inline  Vector < Vector3 >  clip_polygon ( const  Vector < Vector3 >  & polygon ,  const  Plane  & p_plane )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-14 01:22:15 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										enum  LocationCache  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											LOC_INSIDE  =  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											LOC_BOUNDARY  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											LOC_OUTSIDE  =  - 1 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-14 01:22:15 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( polygon . size ( )  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-14 01:22:15 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  polygon ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  * location_cache  =  ( int  * ) alloca ( sizeof ( int )  *  polygon . size ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-14 01:22:15 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  inside_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  outside_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( int  a  =  0 ;  a  <  polygon . size ( ) ;  a + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											//real_t p_plane.d = (*this) * polygon[a];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											real_t  dist  =  p_plane . distance_to ( polygon [ a ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( dist  <  - CMP_POINT_IN_PLANE_EPSILON )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-14 01:22:15 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												location_cache [ a ]  =  LOC_INSIDE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												inside_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( dist  >  CMP_POINT_IN_PLANE_EPSILON )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													location_cache [ a ]  =  LOC_OUTSIDE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													outside_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													location_cache [ a ]  =  LOC_BOUNDARY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( outside_count  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  polygon ;  // no changes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( inside_count  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  Vector < Vector3 > ( ) ;  //empty
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										long  previous  =  polygon . size ( )  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector < Vector3 >  clipped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( int  index  =  0 ;  index  <  polygon . size ( ) ;  index + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  loc  =  location_cache [ index ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( loc  = =  LOC_OUTSIDE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( location_cache [ previous ]  = =  LOC_INSIDE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													const  Vector3  & v1  =  polygon [ previous ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													const  Vector3  & v2  =  polygon [ index ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Vector3  segment  =  v1  -  v2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													real_t  den  =  p_plane . normal . dot ( segment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													real_t  dist  =  p_plane . distance_to ( v1 )  /  den ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													dist  =  - dist ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													clipped . push_back ( v1  +  segment  *  dist ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-14 01:22:15 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												const  Vector3  & v1  =  polygon [ index ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-14 01:22:15 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ( loc  = =  LOC_INSIDE )  & &  ( location_cache [ previous ]  = =  LOC_OUTSIDE ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													const  Vector3  & v2  =  polygon [ previous ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Vector3  segment  =  v1  -  v2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													real_t  den  =  p_plane . normal . dot ( segment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													real_t  dist  =  p_plane . distance_to ( v1 )  /  den ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													dist  =  - dist ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													clipped . push_back ( v1  +  segment  *  dist ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-14 01:22:15 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												clipped . push_back ( v1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											previous  =  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  clipped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  Vector < int >  triangulate_polygon ( const  Vector < Vector2 >  & p_polygon )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector < int >  triangles ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! Triangulate : : triangulate ( p_polygon ,  triangles ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  Vector < int > ( ) ;  //fail
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  triangles ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  Vector < Vector < Vector2 >  >  ( * _decompose_func ) ( const  Vector < Vector2 >  & p_polygon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  Vector < Vector < Vector2 >  >  decompose_polygon ( const  Vector < Vector2 >  & p_polygon )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( _decompose_func ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  _decompose_func ( p_polygon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  Vector < Vector < Vector2 >  > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  PoolVector < PoolVector < Face3 >  >  separate_objects ( PoolVector < Face3 >  p_array ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  PoolVector < Face3 >  wrap_geometry ( PoolVector < Face3 >  p_array ,  real_t  * p_error  =  NULL ) ;  ///< create a "wrap" that encloses the given geometry
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  MeshData  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										struct  Face  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Plane  plane ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < int >  indices ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										Vector < Face >  faces ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										struct  Edge  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  a ,  b ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										Vector < Edge >  edges ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector < Vector3 >  vertices ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										void  optimize_vertices ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_FORCE_INLINE_  static  int  get_uv84_normal_bit ( const  Vector3  & p_vector )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  lat  =  Math : : fast_ftoi ( Math : : floor ( Math : : acos ( p_vector . dot ( Vector3 ( 0 ,  1 ,  0 ) ) )  *  4.0  /  Math_PI  +  0.5 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( lat  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  24 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( lat  = =  4 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  25 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  lon  =  Math : : fast_ftoi ( Math : : floor ( ( Math_PI  +  Math : : atan2 ( p_vector . x ,  p_vector . z ) )  *  8.0  /  ( Math_PI  *  2.0 )  +  0.5 ) )  %  8 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  lon  +  ( lat  -  1 )  *  8 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_FORCE_INLINE_  static  int  get_uv84_normal_bit_neighbors ( int  p_idx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_idx  = =  24 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  1  |  2  |  4  |  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( p_idx  = =  25 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ( 1  < <  23 )  |  ( 1  < <  22 )  |  ( 1  < <  21 )  |  ( 1  < <  20 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  ret  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ( p_idx  %  8 )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  | =  ( 1  < <  ( p_idx  +  7 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ret  | =  ( 1  < <  ( p_idx  -  1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( p_idx  %  8 )  = =  7 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  | =  ( 1  < <  ( p_idx  -  7 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ret  | =  ( 1  < <  ( p_idx  +  1 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  mask  =  ret  |  ( 1  < <  p_idx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p_idx  <  8 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  | =  24 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ret  | =  mask  > >  8 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p_idx  > =  16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  | =  25 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ret  | =  mask  < <  8 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  real_t  vec2_cross ( const  Point2  & O ,  const  Point2  & A ,  const  Point2  & B )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 14:35:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  ( real_t ) ( A . x  -  O . x )  *  ( B . y  -  O . y )  -  ( real_t ) ( A . y  -  O . y )  *  ( B . x  -  O . x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 09:06:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Returns a list of points on the convex hull in counter-clockwise order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Note: the last point in the returned list is the same as the first one.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  Vector < Point2 >  convex_hull_2d ( Vector < Point2 >  P )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 09:06:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  n  =  P . size ( ) ,  k  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Vector < Point2 >  H ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										H . resize ( 2  *  n ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 09:06:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Sort points lexicographically
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										P . sort ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Build lower hull
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( int  i  =  0 ;  i  <  n ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											while  ( k  > =  2  & &  vec2_cross ( H [ k  -  2 ] ,  H [ k  -  1 ] ,  P [ i ] )  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												k - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 09:06:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											H [ k + + ]  =  P [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Build upper hull
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( int  i  =  n  -  2 ,  t  =  k  +  1 ;  i  > =  0 ;  i - - )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											while  ( k  > =  t  & &  vec2_cross ( H [ k  -  2 ] ,  H [ k  -  1 ] ,  P [ i ] )  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												k - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 09:06:53 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											H [ k + + ]  =  P [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										H . resize ( k ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  H ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-07 01:31:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-07 18:25:37 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  MeshData  build_convex_mesh ( const  PoolVector < Plane >  & p_planes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  PoolVector < Plane >  build_sphere_planes ( real_t  p_radius ,  int  p_lats ,  int  p_lons ,  Vector3 : : Axis  p_axis  =  Vector3 : : AXIS_Z ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  PoolVector < Plane >  build_box_planes ( const  Vector3  & p_extents ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  PoolVector < Plane >  build_cylinder_planes ( real_t  p_radius ,  real_t  p_height ,  int  p_sides ,  Vector3 : : Axis  p_axis  =  Vector3 : : AXIS_Z ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  PoolVector < Plane >  build_capsule_planes ( real_t  p_radius ,  real_t  p_height ,  int  p_sides ,  int  p_lats ,  Vector3 : : Axis  p_axis  =  Vector3 : : AXIS_Z ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-05 16:44:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  void  make_atlas ( const  Vector < Size2i >  & p_rects ,  Vector < Point2i >  & r_result ,  Size2i  & r_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif