KiCad PCB EDA Suite
3d_math.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
5  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
30 #ifndef _3D_MATH_H
31 #define _3D_MATH_H
32 
34 #include "3d_fastmath.h"
35 
36 // https://en.wikipedia.org/wiki/Spherical_coordinate_system
43 inline SFVEC3F SphericalToCartesian( float aInclination, float aAzimuth )
44 {
45  float sinInc = glm::sin( aInclination );
46  return SFVEC3F( sinInc * glm::cos( aAzimuth ),
47  sinInc * glm::sin( aAzimuth ),
48  glm::cos( aInclination ) );
49 }
50 
51 
52 // https://pathtracing.wordpress.com/2011/03/03/cosine-weighted-hemisphere/
53 // !TODO: this is not correct because it is not a gaussian random
55 {
56  // It was experienced that this function is slow! do not use it :/
57  // SFVEC3F b( (rand()/(float)RAND_MAX) - 0.5f,
58  // (rand()/(float)RAND_MAX) - 0.5f,
59  // (rand()/(float)RAND_MAX) - 0.5f );
60 
61  SFVEC3F b( Fast_RandFloat() * 0.5f,
62  Fast_RandFloat() * 0.5f,
63  Fast_RandFloat() * 0.5f );
64 
65  return b;
66 }
67 
68 
69 // https://pathtracing.wordpress.com/2011/03/03/cosine-weighted-hemisphere/
71 {
72  const float Xi1 = (float)rand() / (float)RAND_MAX;
73  const float Xi2 = (float)rand() / (float)RAND_MAX;
74 
75  const float theta = acos( sqrt( 1.0f - Xi1 ) );
76  const float phi = 2.0f * glm::pi<float>() * Xi2;
77 
78  const float xs = sinf( theta ) * cosf( phi );
79  const float ys = cosf( theta );
80  const float zs = sinf( theta ) * sinf( phi );
81 
82  const SFVEC3F y( n.x, n.y, n.z );
83  SFVEC3F h = y;
84 
85  if( fabs( h.x ) <= fabs( h.y ) && fabs( h.x ) <= fabs( h.z ) )
86  h.x= 1.0f;
87  else if( fabs( h.y ) <= fabs( h.x ) && fabs( h.y ) <= fabs( h.z ) )
88  h.y= 1.0f;
89  else
90  h.z= 1.0f;
91 
92 
93  const SFVEC3F x = glm::normalize( glm::cross( h, y ) );
94  const SFVEC3F z = glm::normalize( glm::cross( x, y ) );
95 
96  SFVEC3F direction = xs * x + ys * y + zs * z;
97  return glm::normalize( direction );
98 }
99 
100 
113 inline bool Refract( const SFVEC3F &aInVector,
114  const SFVEC3F &aNormal,
115  float aRin_over_Rout,
116  SFVEC3F &aOutVector )
117 {
118  float cosThetaI = -glm::dot( aNormal, aInVector );
119  float sin2ThetaI = glm::max( 0.0f, 1.0f - cosThetaI * cosThetaI );
120  float sin2ThetaT = aRin_over_Rout * aRin_over_Rout * sin2ThetaI;
121 
122  // Handle total internal reflection for transmission
123  if( sin2ThetaT >= 1.0f )
124  return false;
125 
126  float cosThetaT = sqrtf( 1.0f - sin2ThetaT );
127 
128  aOutVector = glm::normalize( aRin_over_Rout * aInVector +
129  ( aRin_over_Rout * cosThetaI - cosThetaT ) *
130  aNormal );
131 
132  return true;
133 }
134 
135 
136 inline float mapf( float x,
137  float in_min,
138  float in_max,
139  float out_min,
140  float out_max)
141 {
142  x = glm::clamp( x, in_min, in_max );
143 
144  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
145 }
146 
147 inline float RGBtoGray( const SFVEC3F &aColor )
148 {
149  return (aColor.r * 0.2126f +
150  aColor.g * 0.7152f +
151  aColor.b * 0.0722f);
152 }
153 
154 inline SFVEC3F MaterialDiffuseToColorCAD( const SFVEC3F &aDiffuseColor )
155 {
156  // convert to a discret scale of grays
157  const float luminance = glm::min( (((float)((unsigned int) ( 4.0f *
158  RGBtoGray( aDiffuseColor ) ) ) + 0.5f) /
159  4.0f) * 1.0f,
160  1.0f );
161 
162  const float maxValue = glm::max( glm::max( glm::max( aDiffuseColor.r,
163  aDiffuseColor.g),
164  aDiffuseColor.b ),
165  FLT_EPSILON );
166 
167  return (aDiffuseColor / SFVEC3F(maxValue) ) * 0.125f + luminance* 0.875f;
168 }
169 
170 
171 // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJ4KngqMiIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MCwiZXEiOiItKCh4LTEpXjIpKjIrMSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjM4NzUwMDAwMDAwMDAwMDIiLCIxLjg2MjQ5OTk5OTk5OTk5OTgiLCItMC43IiwiMS4zIl19XQ--
172 inline float QuadricEasingInOut( float t )
173 {
174  if( t <= 0.5f )
175  {
176  return t * t * 2.0f;
177  }
178  else
179  {
180  t = t - 1.0f;
181 
182  return -2.0f * (t * t) + 1.0f;
183  }
184 }
185 
186 
187 // http://www.wolframalpha.com/input/?i=t%5E2(3-2t)
188 inline float BezierBlend( float t )
189 {
190  return t * t * ( 3.0f - 2.0f * t );
191 }
192 
193 #endif // 3D_MATH_H
float RGBtoGray(const SFVEC3F &aColor)
Definition: 3d_math.h:147
Defines math related functions.
float BezierBlend(float t)
Definition: 3d_math.h:188
float QuadricEasingInOut(float t)
Definition: 3d_math.h:172
float mapf(float x, float in_min, float in_max, float out_min, float out_max)
Definition: 3d_math.h:136
SFVEC3F CosWeightedRandomHemisphereDirection(const SFVEC3F &n)
Definition: 3d_math.h:70
float Fast_RandFloat()
Definition: 3d_fastmath.cpp:45
bool Refract(const SFVEC3F &aInVector, const SFVEC3F &aNormal, float aRin_over_Rout, SFVEC3F &aOutVector)
Refract Based on: https://github.com/mmp/pbrt-v3/blob/master/src/core/reflection.h See also: http://w...
Definition: 3d_math.h:113
SFVEC3F UniformRandomHemisphereDirection()
Definition: 3d_math.h:54
#define max(a, b)
Definition: auxiliary.h:86
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:154
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
SFVEC3F SphericalToCartesian(float aInclination, float aAzimuth)
SphericalToCartesian.
Definition: 3d_math.h:43
#define min(a, b)
Definition: auxiliary.h:85