Nori  23
frame.h
1 /*
2  This file is part of Nori, a simple educational ray tracer
3 
4  Copyright (c) 2015 by Wenzel Jakob
5 
6  Nori is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Nori is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #if !defined(__NORI_FRAME_H)
20 #define __NORI_FRAME_H
21 
22 #include <nori/vector.h>
23 
24 NORI_NAMESPACE_BEGIN
25 
33 struct Frame {
34  Vector3f s, t;
35  Normal3f n;
36 
38  Frame() { }
39 
41  Frame(const Vector3f &s, const Vector3f &t, const Normal3f &n)
42  : s(s), t(t), n(n) { }
43 
45  Frame(const Vector3f &x, const Vector3f &y, const Vector3f &z)
46  : s(x), t(y), n(z) { }
47 
49  Frame(const Vector3f &n) : n(n) {
50  coordinateSystem(n, s, t);
51  }
52 
54  Vector3f toLocal(const Vector3f &v) const {
55  return Vector3f(
56  v.dot(s), v.dot(t), v.dot(n)
57  );
58  }
59 
61  Vector3f toWorld(const Vector3f &v) const {
62  return s * v.x() + t * v.y() + n * v.z();
63  }
64 
67  static float cosTheta(const Vector3f &v) {
68  return v.z();
69  }
70 
73  static float sinTheta(const Vector3f &v) {
74  float temp = sinTheta2(v);
75  if (temp <= 0.0f)
76  return 0.0f;
77  return std::sqrt(temp);
78  }
79 
82  static float tanTheta(const Vector3f &v) {
83  float temp = 1 - v.z()*v.z();
84  if (temp <= 0.0f)
85  return 0.0f;
86  return std::sqrt(temp) / v.z();
87  }
88 
91  static float sinTheta2(const Vector3f &v) {
92  return 1.0f - v.z() * v.z();
93  }
94 
97  static float sinPhi(const Vector3f &v) {
98  float sinTheta = Frame::sinTheta(v);
99  if (sinTheta == 0.0f)
100  return 1.0f;
101  return clamp(v.y() / sinTheta, -1.0f, 1.0f);
102  }
103 
106  static float cosPhi(const Vector3f &v) {
107  float sinTheta = Frame::sinTheta(v);
108  if (sinTheta == 0.0f)
109  return 1.0f;
110  return clamp(v.x() / sinTheta, -1.0f, 1.0f);
111  }
112 
116  static float sinPhi2(const Vector3f &v) {
117  return clamp(v.y() * v.y() / sinTheta2(v), 0.0f, 1.0f);
118  }
119 
123  static float cosPhi2(const Vector3f &v) {
124  return clamp(v.x() * v.x() / sinTheta2(v), 0.0f, 1.0f);
125  }
126 
128  bool operator==(const Frame &frame) const {
129  return frame.s == s && frame.t == t && frame.n == n;
130  }
131 
133  bool operator!=(const Frame &frame) const {
134  return !operator==(frame);
135  }
136 
138  std::string toString() const {
139  return tfm::format(
140  "Frame[\n"
141  " s = %s,\n"
142  " t = %s,\n"
143  " n = %s\n"
144  "]", s.toString(), t.toString(), n.toString());
145  }
146 };
147 
148 NORI_NAMESPACE_END
149 
150 #endif /* __NORI_FRAME_H */
Stores a three-dimensional orthonormal coordinate frame.
Definition: frame.h:33
static float cosPhi2(const Vector3f &v)
Assuming that the given direction is in the local coordinate system, return the squared cosine of the...
Definition: frame.h:123
Frame(const Vector3f &x, const Vector3f &y, const Vector3f &z)
Construct a frame from the given orthonormal vectors.
Definition: frame.h:45
static float sinTheta(const Vector3f &v)
Assuming that the given direction is in the local coordinate system, return the sine of the angle bet...
Definition: frame.h:73
Frame(const Vector3f &s, const Vector3f &t, const Normal3f &n)
Given a normal and tangent vectors, construct a new coordinate frame.
Definition: frame.h:41
static float cosPhi(const Vector3f &v)
Assuming that the given direction is in the local coordinate system, return the cosine of the phi par...
Definition: frame.h:106
Vector3f toWorld(const Vector3f &v) const
Convert from local coordinates to world coordinates.
Definition: frame.h:61
static float sinPhi(const Vector3f &v)
Assuming that the given direction is in the local coordinate system, return the sine of the phi param...
Definition: frame.h:97
static float tanTheta(const Vector3f &v)
Assuming that the given direction is in the local coordinate system, return the tangent of the angle ...
Definition: frame.h:82
std::string toString() const
Return a human-readable string summary of this frame.
Definition: frame.h:138
static float cosTheta(const Vector3f &v)
Assuming that the given direction is in the local coordinate system, return the cosine of the angle b...
Definition: frame.h:67
bool operator==(const Frame &frame) const
Equality test.
Definition: frame.h:128
Frame()
Default constructor – performs no initialization!
Definition: frame.h:38
Frame(const Vector3f &n)
Construct a new coordinate frame from a single vector.
Definition: frame.h:49
static float sinTheta2(const Vector3f &v)
Assuming that the given direction is in the local coordinate system, return the squared sine of the a...
Definition: frame.h:91
bool operator!=(const Frame &frame) const
Inequality test.
Definition: frame.h:133
static float sinPhi2(const Vector3f &v)
Assuming that the given direction is in the local coordinate system, return the squared sine of the p...
Definition: frame.h:116
Vector3f toLocal(const Vector3f &v) const
Convert from world coordinates to local coordinates.
Definition: frame.h:54
3-dimensional surface normal representation
Definition: vector.h:133
std::string toString() const
Return a human-readable string summary.
Definition: vector.h:162
std::string toString() const
Return a human-readable string summary.
Definition: vector.h:71