Changeset 372
- Timestamp:
- 05/22/15 16:50:38 (10 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/core/common.hh
r369 r372 136 136 #define NV_RESTRICT __declspec(restrict) 137 137 #define NV_RESTRICT_VAR __restrict 138 #define NV_NOEXCEPT throw() 138 139 //#define NV_CONSTEXPR 139 140 #elif NV_COMPILER == NV_GNUC || NV_COMPILER == NV_CLANG … … 143 144 #define NV_RESTRICT __restrict__ 144 145 #define NV_RESTRICT_VAR __restrict__ 146 #define NV_NOEXCEPT noexcept 145 147 //#define NV_CONSTEXPR constexpr 146 148 #else … … 150 152 #define NV_RESTRICT 151 153 #define NV_RESTRICT_VAR 154 #define NV_NOEXCEPT 152 155 //#define NV_CONSTEXPR 153 156 #endif -
trunk/nv/core/position.hh
r368 r372 17 17 #include <nv/stl/math.hh> 18 18 #include <nv/stl/range.hh> 19 #include <utility>20 19 21 20 namespace nv -
trunk/nv/core/random.hh
r368 r372 10 10 #include <nv/core/common.hh> 11 11 #include <nv/stl/math.hh> 12 #include < random>12 #include <nv/stl/type_traits.hh> 13 13 14 14 namespace nv … … 18 18 { 19 19 public: 20 typedef std::mt19937::result_type result_type;21 typedef std::mt19937::result_typeseed_type;20 typedef unsigned int result_type; // std::mt19937::result_type 21 typedef unsigned int seed_type; 22 22 23 23 random( seed_type seed = 0 ); … … 38 38 { 39 39 return glm::detail::tvec2<T>( 40 range_impl( min.x, max.x, std::is_floating_point<T>() ),41 range_impl( min.y, max.y, std::is_floating_point<T>() )40 range_impl( min.x, max.x, is_floating_point<T>() ), 41 range_impl( min.y, max.y, is_floating_point<T>() ) 42 42 ); 43 43 } … … 47 47 { 48 48 return glm::detail::tvec3<T>( 49 range_impl( min.x, max.x, std::is_floating_point<T>() ),50 range_impl( min.y, max.y, std::is_floating_point<T>() ),51 range_impl( min.z, max.z, std::is_floating_point<T>() )49 range_impl( min.x, max.x, is_floating_point<T>() ), 50 range_impl( min.y, max.y, is_floating_point<T>() ), 51 range_impl( min.z, max.z, is_floating_point<T>() ) 52 52 ); 53 53 } … … 57 57 { 58 58 return glm::detail::tvec4<T>( 59 range_impl( min.x, max.x, std::is_floating_point<T>() ),60 range_impl( min.y, max.y, std::is_floating_point<T>() ),61 range_impl( min.z, max.z, std::is_floating_point<T>() ),62 range_impl( min.w, max.w, std::is_floating_point<T>() )59 range_impl( min.x, max.x, is_floating_point<T>() ), 60 range_impl( min.y, max.y, is_floating_point<T>() ), 61 range_impl( min.z, max.z, is_floating_point<T>() ), 62 range_impl( min.w, max.w, is_floating_point<T>() ) 63 63 ); 64 64 } … … 163 163 164 164 template <typename T> 165 T range_impl( T min, T max, const std::true_type& )165 T range_impl( T min, T max, const true_type& ) 166 166 { 167 std::uniform_real_distribution<T> dist( min, max ); 168 return dist( rng ); 167 return frange( min, max ); 169 168 } 170 169 171 170 template <typename T> 172 T range_impl( T min, T max, const std::false_type& )171 T range_impl( T min, T max, const false_type& ) 173 172 { 174 std::uniform_int_distribution<T> dist( min, max ); 175 return dist( rng ); 173 return srange( min, max ); 176 174 } 177 175 private: 178 std::mt19937 rng; 176 // temporary solution until we get rid of std::random 177 char m_data[16 * 1024]; 179 178 }; 180 179 -
trunk/nv/core/types.hh
r370 r372 12 12 #include <unordered_map> 13 13 #include <vector> 14 15 namespace std 16 { 17 template<> 18 struct hash < nv::type_index > 19 { 20 size_t operator()( nv::type_index key ) const 21 { 22 return ( key.hash_code() ); 23 } 24 }; 25 } 14 26 15 27 namespace nv -
trunk/nv/stl/memory.hh
r369 r372 18 18 #include <nv/core/common.hh> 19 19 #include <nv/stl/type_traits.hh> 20 #include <iterator> 20 21 21 22 namespace nv -
trunk/nv/stl/string.hh
r368 r372 294 294 #endif 295 295 296 // These could be done much better 297 template <typename T> 298 struct is_cstring 299 : public integral_constant < bool, 300 is_same< char *, typename std::decay< T >::type >::value || 301 is_same< const char *, typename std::decay< T >::type >::value > 302 { 303 }; 304 305 template <typename T> 306 struct is_stdstring 307 : public integral_constant < bool, 308 is_same< std::string, typename std::decay< T >::type >::value 309 > 310 { 311 }; 312 313 template < typename T > struct is_string : public integral_constant < bool, is_stdstring<T>::value || is_cstring<T>::value > {}; 314 315 template<typename T> 316 struct is_container 317 { 318 private: 319 typedef char yes; 320 typedef struct { char array[2]; } no; 321 template<typename C> static yes test( typename C::iterator* ); 322 template<typename C> static no test( ... ); 323 public: 324 static const bool value = sizeof( test<T>( 0 ) ) == sizeof( yes ); 325 }; 326 327 template<> 328 struct is_container < std::string > 329 { 330 static const bool value = false; 331 }; 332 333 334 296 335 class string_ref; 297 336 -
trunk/nv/stl/type_traits.hh
r370 r372 19 19 #include <type_traits> 20 20 #include <typeinfo> 21 #include <string>22 21 23 22 namespace nv 24 23 { 25 24 26 // These could be done much better 27 template <typename T> 28 struct is_cstring 29 : public std::integral_constant<bool, 30 std::is_same< char *, typename std::decay< T >::type >::value || 31 std::is_same< const char *, typename std::decay< T >::type >::value > 32 {}; 33 34 template <typename T> 35 struct is_stdstring 36 : public std::integral_constant<bool, 37 std::is_same< std::string, typename std::decay< T >::type >::value 38 > 39 {}; 40 41 template < typename T > struct is_string : public std::integral_constant<bool, is_stdstring<T>::value || is_cstring<T>::value> {}; 42 43 // Just for once, MSVC is the good guy, and everybody else sucks. 44 // Remove, once requiring standard-compliant CLANG/GCC versions. 45 #if NV_COMPILER == NV_MSVC 46 using std::underlying_type; 47 #elif NV_COMPILER == NV_CLANG 25 template< typename T, T VALUE> 26 struct integral_constant 27 { 28 static const T value = VALUE; 29 typedef T value_type; 30 typedef integral_constant<T, VALUE> type; 31 operator value_type() const { return ( value ); } 32 }; 33 34 typedef integral_constant<bool, true> true_type; 35 typedef integral_constant<bool, false> false_type; 36 37 template< bool TEST, typename T = void> 38 struct enable_if {}; 39 40 template< typename T > 41 struct enable_if< true, T > 42 { 43 typedef T type; 44 }; 45 46 template< bool TEST, typename T1, typename T2 > 47 struct conditional 48 { 49 typedef T2 type; 50 }; 51 52 template< typename T1, typename T2> 53 struct conditional < true, T1, T2 > 54 { 55 typedef T1 type; 56 }; 57 58 template< typename T1, typename T2 > 59 struct is_same : false_type {}; 60 61 template< typename T > 62 struct is_same < T, T > : true_type{}; 63 64 template< typename T > 65 struct is_lvalue_reference : false_type {}; 66 67 template< typename T > 68 struct is_lvalue_reference < T& > : true_type{}; 69 70 template< typename T > 71 struct is_rvalue_reference : false_type {}; 72 73 template< typename T > 74 struct is_rvalue_reference < T&& > : true_type{}; 75 76 template < typename T > 77 struct is_enum : integral_constant < bool, __is_enum( T ) > {}; 78 79 template< typename T > 80 struct remove_reference 81 { 82 typedef T type; 83 }; 84 85 template< typename T > 86 struct remove_reference < T& > 87 { 88 typedef T type; 89 }; 90 91 template< typename T > 92 struct remove_reference < T&& > 93 { 94 typedef T type; 95 }; 96 97 template< typename T > 98 struct remove_const 99 { 100 typedef T type; 101 }; 102 103 template< typename T > 104 struct remove_const < const T > 105 { 106 typedef T type; 107 }; 108 109 template< typename T > 110 struct remove_const < const T[] > 111 { 112 typedef T type[]; 113 }; 114 115 template< typename T, unsigned int N > 116 struct remove_const < const T[N] > 117 { 118 typedef T type[N]; 119 }; 120 121 template< typename T > 122 struct remove_volatile 123 { 124 typedef T type; 125 }; 126 127 template< typename T > 128 struct remove_volatile < volatile T > 129 { 130 typedef T type; 131 }; 132 133 template< typename T > 134 struct remove_volatile < volatile T[] > 135 { 136 typedef T type[]; 137 }; 138 139 template< typename T, unsigned int N > 140 struct remove_volatile < volatile T[N] > 141 { 142 typedef T type[N]; 143 }; 144 145 template< typename T > 146 struct remove_cv 147 { 148 typedef typename remove_const< typename remove_volatile<T>::type >::type 149 type; 150 }; 151 152 namespace detail 153 { 154 // TODO: these seem to simple compared to MSVC/GCC - so we'll leave them in 155 // detail - research why it is so. 156 template < typename T > 157 struct is_const : public false_type {}; 158 template < typename T > 159 struct is_const < T const > : public true_type {}; 160 template < typename T > 161 struct is_volatile : public false_type {}; 162 template < typename T > 163 struct is_volatile < T volatile > : public true_type {}; 164 // TODO END 165 166 template< typename T, bool CONST, bool VOLATILE> 167 struct cv_selector; 168 169 template< typename T > 170 struct cv_selector < T, false, false > { typedef T type; }; 171 172 template< typename T > 173 struct cv_selector < T, true, false > { typedef const T type; }; 174 175 template< typename T > 176 struct cv_selector < T, false, true > { typedef volatile T type; }; 177 178 template< typename T > 179 struct cv_selector < T, true, true > { typedef const volatile T type; }; 180 181 template< typename SOURCE, typename TARGET, 182 bool CONST = is_const<SOURCE>::value, 183 bool VOLATILE = is_volatile<SOURCE>::value > 184 struct match_cv 185 { 186 typedef typename cv_selector< TARGET, CONST, VOLATILE >::type type; 187 }; 188 189 template< typename T > 190 struct is_integral_impl : false_type {}; 191 192 template<> struct is_integral_impl< bool > : true_type {}; 193 template<> struct is_integral_impl< char > : true_type {}; 194 template<> struct is_integral_impl< signed char > : true_type {}; 195 template<> struct is_integral_impl< unsigned char > : true_type {}; 196 template<> struct is_integral_impl< wchar_t > : true_type {}; 197 template<> struct is_integral_impl< signed short > : true_type {}; 198 template<> struct is_integral_impl< unsigned short > : true_type {}; 199 template<> struct is_integral_impl< signed int > : true_type {}; 200 template<> struct is_integral_impl< unsigned int > : true_type {}; 201 template<> struct is_integral_impl< signed long > : true_type {}; 202 template<> struct is_integral_impl< unsigned long > : true_type {}; 203 template<> struct is_integral_impl< sint64 > : true_type {}; 204 template<> struct is_integral_impl< uint64 > : true_type {}; 205 206 template< typename T > struct is_floating_point_impl : false_type {}; 207 208 template<> struct is_floating_point_impl< float > : true_type{}; 209 template<> struct is_floating_point_impl< double > : true_type{}; 210 template<> struct is_floating_point_impl< long double > : true_type{}; 211 212 template < typename T > 213 struct signed_type 214 { 215 typedef T type; 216 }; 217 218 template<> struct signed_type < char > { typedef signed char type; }; 219 template<> struct signed_type < unsigned char > { typedef signed char type; }; 220 template<> struct signed_type < unsigned short > { typedef signed short type; }; 221 template<> struct signed_type < unsigned int > { typedef signed int type; }; 222 template<> struct signed_type < unsigned long > { typedef signed long type; }; 223 template<> struct signed_type < uint64 > { typedef sint64 type; }; 224 225 template < typename T > 226 struct unsigned_type 227 { 228 typedef T type; 229 }; 230 231 template<> struct unsigned_type < char > { typedef unsigned char type; }; 232 template<> struct unsigned_type < signed char > { typedef unsigned char type; }; 233 template<> struct unsigned_type < signed short > { typedef unsigned short type; }; 234 template<> struct unsigned_type < signed int > { typedef unsigned int type; }; 235 template<> struct unsigned_type < signed long > { typedef unsigned long type; }; 236 template<> struct unsigned_type < sint64 > { typedef uint64 type; }; 237 238 template < typename T, bool IS_ENUM = is_enum< T >::value > 239 struct make_signed_impl; 240 241 template < typename T > 242 struct make_signed_impl < T, false > 243 { 244 private: 245 typedef signed_type<typename remove_cv<T>::type> signed_type_result; 246 public: 247 typedef match_cv< T, typename signed_type_result::type > type; 248 }; 249 250 template < typename T > 251 struct make_signed_impl < T, true > 252 { 253 private: 254 static const bool size1test = sizeof( T ) <= sizeof( signed char ); 255 static const bool size2test = sizeof( T ) <= sizeof( signed short ); 256 static const bool size4test = sizeof( T ) <= sizeof( signed int ); 257 typedef typename conditional<size4test, signed int, signed long>::type test4type; 258 typedef typename conditional<size2test, signed short, test4type>::type test2type; 259 public: 260 typedef typename conditional<size1test, signed char, test2type>::type type; 261 }; 262 263 template < typename T, bool IS_ENUM = is_enum< T >::value > 264 struct make_unsigned_impl; 265 266 template < typename T > 267 struct make_unsigned_impl < T, false > 268 { 269 private: 270 typedef unsigned_type<typename remove_cv<T>::type> unsigned_type_result; 271 public: 272 typedef match_cv< T, typename unsigned_type_result::type > type; 273 }; 274 275 template < typename T > 276 struct make_unsigned_impl < T, true > 277 { 278 private: 279 static const bool size1test = sizeof( T ) <= sizeof( unsigned char ); 280 static const bool size2test = sizeof( T ) <= sizeof( unsigned short ); 281 static const bool size4test = sizeof( T ) <= sizeof( unsigned int ); 282 typedef typename conditional<size4test, unsigned int, unsigned long>::type test4type; 283 typedef typename conditional<size2test, unsigned short, test4type>::type test2type; 284 public: 285 typedef typename conditional<size1test, unsigned char, test2type>::type type; 286 }; 287 } 288 289 template < typename T > 290 struct make_signed 291 { 292 typedef typename detail::make_signed_impl<T>::type type; 293 }; 294 295 template <> struct make_signed < bool > ; 296 297 template < typename T > 298 struct make_unsigned 299 { 300 typedef typename detail::make_unsigned_impl<T>::type type; 301 }; 302 303 template <> struct make_unsigned < bool > ; 304 305 306 template< typename T > 307 struct is_integral : detail::is_integral_impl< typename remove_cv<T>::type > 308 { 309 }; 310 311 template< typename T > 312 struct is_floating_point : detail::is_floating_point_impl< typename remove_cv<T>::type > 313 { 314 }; 315 316 #if NV_COMPILER == NV_MSVC || NV_COMPILER == NV_CLANG 48 317 template < typename T > 49 318 struct underlying_type 50 319 { 51 typedef __underlying_type( T) type;320 typedef __underlying_type( T ) type; 52 321 }; 53 322 #else … … 55 324 struct underlying_type 56 325 { 57 typedef typename std::conditional<326 typedef typename conditional < 58 327 T( -1 ) < T( 0 ), 59 typename std::make_signed< T >::type,60 typename std::make_unsigned< T >::type61 > ::type type;328 typename make_signed< T >::type, 329 typename make_unsigned< T >::type 330 > ::type type; 62 331 }; 63 332 #endif … … 128 397 }; 129 398 130 template<typename T>131 struct is_container132 {133 private:134 typedef char yes;135 typedef struct { char array[2]; } no;136 template<typename C> static yes test(typename C::iterator*);137 template<typename C> static no test(...);138 public:139 static const bool value = sizeof(test<T>(0)) == sizeof(yes);140 };141 142 template<>143 struct is_container< std::string > {144 static const bool value = false;145 };146 147 399 template <typename TYPE> 148 400 void construct_object(void* object) … … 163 415 164 416 template< typename T > 165 struct base_underlying_type_helper< T, std::true_type >166 { 167 typedef typename nv::underlying_type<T>::type type;417 struct base_underlying_type_helper< T, true_type > 418 { 419 typedef typename underlying_type<T>::type type; 168 420 }; 169 421 … … 172 424 struct base_underlying_type 173 425 { 174 typedef typename base_underlying_type_helper< T, typename std::is_enum<T>::type >::type type;426 typedef typename base_underlying_type_helper< T, typename is_enum<T>::type >::type type; 175 427 }; 176 428 … … 218 470 } 219 471 220 namespace std221 {222 template<>223 struct hash< nv::type_index >224 {225 size_t operator()( nv::type_index key ) const226 {227 return ( key.hash_code() );228 }229 };230 }231 232 472 #endif // NV_CORE_TYPE_TRAITS_HH -
trunk/src/core/random.cc
r319 r372 7 7 #include "nv/core/random.hh" 8 8 #include "nv/core/time.hh" 9 #include <random> 9 10 10 11 using namespace nv; 11 12 12 13 random::random( random::seed_type seed /*= 0 */ ) 13 : rng( seed == 0 ? randomized_seed() : seed ) 14 { 15 14 { 15 static_assert( sizeof( std::mt19937 ) < sizeof( random::m_data ), "No room for mersenne twister!" ); 16 new (m_data)std::mt19937( seed == 0 ? randomized_seed() : seed ); 16 17 } 17 18 18 19 random::seed_type random::randomize() 19 20 { 21 std::mt19937& rng = *(( std::mt19937* )m_data); 20 22 seed_type seed = randomized_seed(); 21 23 rng.seed( seed ); … … 25 27 void random::set_seed( random::seed_type seed /*= 0 */ ) 26 28 { 29 std::mt19937& rng = *( ( std::mt19937* )m_data ); 27 30 rng.seed( seed == 0 ? randomized_seed() : seed ); 28 31 } … … 36 39 random::result_type random::rand() 37 40 { 41 std::mt19937& rng = *( ( std::mt19937* )m_data ); 38 42 return rng(); 39 43 } … … 41 45 sint32 random::srand( sint32 val ) 42 46 { 47 std::mt19937& rng = *( ( std::mt19937* )m_data ); 43 48 std::uniform_int_distribution<sint32> dist( 0, val - 1 ); 44 49 return dist( rng ); … … 47 52 uint32 random::urand( uint32 val ) 48 53 { 54 std::mt19937& rng = *( ( std::mt19937* )m_data ); 49 55 std::uniform_int_distribution<uint32> dist( 0, val - 1 ); 50 56 return dist( rng ); … … 53 59 f32 random::frand( f32 val ) 54 60 { 61 std::mt19937& rng = *( ( std::mt19937* )m_data ); 55 62 std::uniform_real_distribution<f32> dist( 0, val ); 56 63 return dist( rng ); … … 59 66 sint32 random::srange( sint32 min, sint32 max ) 60 67 { 68 std::mt19937& rng = *( ( std::mt19937* )m_data ); 61 69 std::uniform_int_distribution<sint32> dist( min, max ); 62 70 return dist( rng ); … … 65 73 uint32 random::urange( uint32 min, uint32 max ) 66 74 { 75 std::mt19937& rng = *( ( std::mt19937* )m_data ); 67 76 std::uniform_int_distribution<uint32> dist( min, max ); 68 77 return dist( rng ); … … 71 80 f32 random::frange( f32 min, f32 max ) 72 81 { 82 std::mt19937& rng = *( ( std::mt19937* )m_data ); 73 83 std::uniform_real_distribution<f32> dist( min, max ); 74 84 return dist( rng ); … … 77 87 uint32 random::dice( uint32 count, uint32 sides ) 78 88 { 89 std::mt19937& rng = *( ( std::mt19937* )m_data ); 79 90 std::uniform_int_distribution<uint32> dist( 1, sides ); 80 91 uint32 result = 0; … … 88 99 random::seed_type random::randomized_seed() 89 100 { 101 // TODO: this seems off, as it might often seed the same, use general time 102 // instead 90 103 return narrow_cast< seed_type >( get_ticks() ); 91 104 } … … 93 106 nv::vec2 nv::random::precise_unit_vec2() 94 107 { 108 std::mt19937& rng = *( ( std::mt19937* )m_data ); 95 109 std::uniform_real_distribution<f32> dist( 0, glm::pi<float>() * 2.f ); 96 110 float angle = dist( rng ); … … 100 114 nv::vec3 nv::random::precise_unit_vec3() 101 115 { 116 std::mt19937& rng = *( ( std::mt19937* )m_data ); 102 117 std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f ); 103 118 std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() ); … … 114 129 nv::vec2 nv::random::fast_disk_point() 115 130 { 131 std::mt19937& rng = *( ( std::mt19937* )m_data ); 116 132 std::uniform_real_distribution<f32> dist( 0.0f, 1.0f ); 117 133 float r1 = dist( rng ); … … 124 140 nv::vec2 nv::random::precise_disk_point() 125 141 { 142 std::mt19937& rng = *( ( std::mt19937* )m_data ); 126 143 std::uniform_real_distribution<f32> unit( 0.0f, 1.0f ); 127 144 std::uniform_real_distribution<f32> angle( 0.0f, glm::pi<float>() ); … … 133 150 nv::vec3 nv::random::fast_sphere_point() 134 151 { 152 std::mt19937& rng = *( ( std::mt19937* )m_data ); 135 153 std::uniform_real_distribution<f32> dist01( 0.0f, 1.0f ); 136 154 std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f ); … … 150 168 nv::vec3 nv::random::precise_sphere_point() 151 169 { 170 std::mt19937& rng = *( ( std::mt19937* )m_data ); 152 171 std::uniform_real_distribution<f32> dist01( 0.0f, 1.0f ); 153 172 std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f ); … … 166 185 nv::vec2 nv::random::precise_ellipse_point( const vec2& radii ) 167 186 { 187 std::mt19937& rng = *( ( std::mt19937* )m_data ); 168 188 std::uniform_real_distribution<f32> distx( -radii.x, radii.x ); 169 189 std::uniform_real_distribution<f32> disty( -radii.y, radii.y ); … … 184 204 nv::vec3 nv::random::precise_ellipsoid_point( const vec3& radii ) 185 205 { 206 std::mt19937& rng = *( ( std::mt19937* )m_data ); 186 207 std::uniform_real_distribution<f32> distx( -radii.x, radii.x ); 187 208 std::uniform_real_distribution<f32> disty( -radii.y, radii.y ); … … 204 225 nv::vec2 nv::random::fast_hollow_disk_point( float iradius, float oradius ) 205 226 { 227 std::mt19937& rng = *( ( std::mt19937* )m_data ); 206 228 float idist2 = iradius * iradius; 207 229 float odist2 = oradius * oradius; … … 217 239 nv::vec3 nv::random::fast_hollow_sphere_point( float iradius, float oradius ) 218 240 { 241 std::mt19937& rng = *( ( std::mt19937* )m_data ); 219 242 float idist3 = iradius * iradius * iradius; 220 243 float odist3 = oradius * oradius * oradius; … … 231 254 nv::vec2 nv::random::fast_hollow_ellipse_point( const vec2& iradii, const vec2& oradii ) 232 255 { 233 vec2 iradii2 = iradii * iradii; 256 std::mt19937& rng = *( ( std::mt19937* )m_data ); 257 vec2 iradii2 = iradii * iradii; 234 258 vec2 opoint = ellipse_edge( oradii ); 235 259 vec2 opoint2 = opoint * opoint; … … 251 275 nv::vec3 nv::random::fast_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii ) 252 276 { 253 vec3 iradii2 = iradii * iradii; 277 std::mt19937& rng = *( ( std::mt19937* )m_data ); 278 vec3 iradii2 = iradii * iradii; 254 279 vec3 opoint = ellipsoid_edge( oradii ); 255 280 vec3 opoint2 = opoint * opoint;
Note: See TracChangeset
for help on using the changeset viewer.