commit
05ffa6048e
@ -0,0 +1,2 @@
|
||||
build/
|
||||
.vscode/
|
@ -0,0 +1,8 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(ray)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-g -Wall")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
add_executable(ray main.cpp )
|
@ -0,0 +1,121 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
@ -0,0 +1,101 @@
|
||||
#ifndef GEOH
|
||||
#define GEOH
|
||||
#include <cmath>
|
||||
|
||||
#include "ray.h"
|
||||
using namespace std;
|
||||
struct hit_record {
|
||||
float t;
|
||||
vec3 p;
|
||||
vec3 nv;
|
||||
vec3 kd;
|
||||
float wr;
|
||||
float wt;
|
||||
};
|
||||
|
||||
class hitable { //geometry parent class
|
||||
public:
|
||||
virtual bool hit(const ray &r, float tmin, float tmax, hit_record *rec) const = 0;
|
||||
};
|
||||
|
||||
class sphere : public hitable {
|
||||
public:
|
||||
sphere() {}
|
||||
sphere(vec3 c, float r, vec3 _kd = vec3(1.0, 1.0, 1.0), float w_ri = 0.0f, float w_ti = 0.0f) : center(c), radius(r), kd(_kd), w_r(w_ri), w_t(w_ti){};
|
||||
bool hit(const ray &r, float tmin, float tmax, hit_record *rec) const;
|
||||
vec3 center;
|
||||
float radius;
|
||||
vec3 kd;
|
||||
float w_r; //reflected
|
||||
float w_t; //transmitted
|
||||
};
|
||||
|
||||
bool sphere::hit(const ray &r, float tmin, float tmax, hit_record *rec) const {
|
||||
float a, b, c, t;
|
||||
a = dot(r.D, r.D);
|
||||
b = 2 * (dot(r.D, (r.O - this->center)));
|
||||
c = dot(r.O - this->center, r.O - this->center) - this->radius * this->radius;
|
||||
if (((b * b) - (4 * a * c)) > 0) {
|
||||
if ((((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin && (((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin) {
|
||||
t = min((((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)), (((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a)));
|
||||
} else if ((((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin) {
|
||||
t = (((-b) - sqrt((b * b) - (4 * a * c))) / (2 * a));
|
||||
} else if ((((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a)) > tmin) {
|
||||
t = (((-b) + sqrt((b * b) - (4 * a * c))) / (2 * a));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (t > tmax || t < tmin) {
|
||||
return false;
|
||||
}
|
||||
if (rec->t > t) {
|
||||
rec->t = t;
|
||||
rec->p = r.point_at_parameter(t);
|
||||
rec->nv = unit_vector(r.point_at_parameter(t) - this->center);
|
||||
rec->kd = this->kd;
|
||||
rec->wr = this->w_r;
|
||||
rec->wt = this->w_t;
|
||||
//cout << t << " " << rec->p << " " << rec->nv << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
vec3 reflect(const vec3 &d, const vec3 &nv) {
|
||||
return d - (2 * dot(d, nv) * nv);
|
||||
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
float clamp(T bot, T top, T targ) {
|
||||
if (targ > top) {
|
||||
return top;
|
||||
}
|
||||
if (targ < bot) {
|
||||
return bot;
|
||||
}
|
||||
return targ;
|
||||
}
|
||||
|
||||
vec3 refract(const vec3 &i, const vec3 &n, float eta) {
|
||||
vec3 I = unit_vector(i);
|
||||
vec3 N = unit_vector(n);
|
||||
//cout << I << " " << N << " " << dot(N, I) << endl;
|
||||
eta = 1 / eta;
|
||||
if (dot(N, I) > 0) {
|
||||
N = -1 * N;
|
||||
eta = 1 / eta;
|
||||
}
|
||||
float k = 1.0f - eta * eta * (1.0 - dot(N, I) * dot(N, I));
|
||||
//cout << k << endl;
|
||||
if (k < 0.0) {
|
||||
return i - (2 * dot(i, n) * n);
|
||||
}
|
||||
|
||||
//cout << eta * I - (eta * dot(N, I) + sqrt(k)) * N << endl;
|
||||
return eta * I - (eta * dot(N, I) + sqrt(k)) * N;
|
||||
}
|
||||
#endif
|
@ -0,0 +1,195 @@
|
||||
#include <cfloat>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "geo.h"
|
||||
#include "ray.h"
|
||||
#include "vec3.h"
|
||||
|
||||
float MAX(float a, float b) { return (a > b) ? a : b; }
|
||||
using namespace std;
|
||||
int max_step = 5;
|
||||
|
||||
vec3 shading(vec3 &lightsource, vec3 &intensity, hit_record ht, vec3 kd, const vector<sphere> &list) {
|
||||
/*
|
||||
define L, N by yourself
|
||||
*/
|
||||
vec3 L = lightsource - ht.p;
|
||||
vec3 N = ht.nv;
|
||||
ray shadowRay(ht.p, L);
|
||||
|
||||
int intersect = -1;
|
||||
hit_record rec;
|
||||
float closest = FLT_MAX;
|
||||
/*
|
||||
To-do:
|
||||
To find whether the shadowRay hit other object,
|
||||
you should run the function "hit" of all the hitable you created
|
||||
*/
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list[i].hit(shadowRay, 0.001, 10000, &rec)) {
|
||||
intersect += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (intersect == -1) {
|
||||
return kd * intensity * MAX(0, dot(N, unit_vector(L)));
|
||||
} else {
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
vec3 skybox(const ray &r) {
|
||||
vec3 uni_direction = unit_vector(r.direction());
|
||||
float t = 0.5 * (uni_direction.y() + 1);
|
||||
return (1.0 - t) * vec3(1, 1, 1) + t * vec3(0.5, 0.7, 1.0);
|
||||
}
|
||||
|
||||
vec3 trace(const ray &r, const vector<sphere> &list, int depth) {
|
||||
if (r.direction() == vec3(0, 0, 0)) {
|
||||
return vec3(0, 0, 0);
|
||||
}
|
||||
//cout << r.direction() << endl;
|
||||
if (depth >= max_step)
|
||||
return skybox(r); //or return vec3(0,0,0);
|
||||
|
||||
int intersect = -1;
|
||||
vec3 lightsource = vec3(-10, 10, 0);
|
||||
vec3 intensity = vec3(1, 1, 1);
|
||||
hit_record rec;
|
||||
rec.t = 10000;
|
||||
rec.p = vec3(0, 0, 0);
|
||||
rec.nv = vec3(0, 0, 0);
|
||||
float closest = FLT_MAX;
|
||||
/*
|
||||
To-do:
|
||||
To find the nearest object from the origin of the ray,
|
||||
you should run the function "hit" of all the hitable you created
|
||||
*/
|
||||
//cout << "Hit" << endl;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list[i].hit(r, 0.0001, 1000, &rec)) {
|
||||
//cout << intersect << endl;
|
||||
intersect += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (intersect != -1) {
|
||||
/*
|
||||
To-do:
|
||||
1.compute the local color by shading function
|
||||
2.compute the relected color by
|
||||
2.1 compute the reflected direction
|
||||
2.2 define a reflected ray by rec.p and the direction in 2.1
|
||||
2.3 run trace(reflected_ray,list,depth+1);
|
||||
3.compute the transmitted color by
|
||||
3.1 compute the transmitted direction by Snell's law
|
||||
3.2 define a transmitted ray by rec.p and the direction in 3.1
|
||||
3.3 run trace( transmitted_ray, list, depth+1 );
|
||||
4.return the color by the parameter w_r, w_t and the 3 color you computed.
|
||||
*/
|
||||
|
||||
//1.
|
||||
vec3 L = unit_vector(lightsource - rec.p);
|
||||
vec3 colour = (dot(rec.nv, L) >= 0 ? dot(rec.nv, L) : 0) * rec.kd;
|
||||
|
||||
//cout << rec.kd << " " << rec.wr << endl;
|
||||
|
||||
//return colour;
|
||||
|
||||
vec3 shadow = shading(lightsource, intensity, rec, rec.kd, list);
|
||||
colour = 0.2 * colour + 0.8 * shadow;
|
||||
|
||||
if (depth >= 5) {
|
||||
//return 0.5 * vec3(rec.nv.x() + 1, rec.nv.y() + 1, rec.nv.z() + 1);
|
||||
return colour;
|
||||
}
|
||||
if (rec.wr <= 0 && rec.wt <= 0) {
|
||||
return colour;
|
||||
}
|
||||
{
|
||||
vec3 reflection = vec3(0, 0, 0);
|
||||
if ((dot(r.direction(), rec.nv) / r.direction().length() * rec.nv.length()) < 0) {
|
||||
if (rec.wr > 0) {
|
||||
//cout << "reflection " << depth << endl;
|
||||
reflection = trace(ray(rec.p, reflect(r.direction(), rec.nv)), list, (depth + 1));
|
||||
}
|
||||
if (rec.wt <= 0) {
|
||||
//cout << "reflection " << depth << endl;
|
||||
colour = reflection * rec.wr + colour * max(0.0f, (1 - rec.wr));
|
||||
return colour;
|
||||
}
|
||||
//cout << "refraction " << depth << endl;
|
||||
vec3 refraction = trace(ray(rec.p, refract(r.direction(), rec.nv, 1.5)), list, (depth + 1));
|
||||
colour = reflection * rec.wr + refraction * rec.wt + colour * max(0.0f, (1 - rec.wr - rec.wt));
|
||||
} else {
|
||||
//cout << "refraction " << depth << endl;
|
||||
vec3 refraction = trace(ray(rec.p, refract(r.direction(), rec.nv, 1.5)), list, (depth + 1));
|
||||
//cout << "refraction out" << endl;
|
||||
colour = refraction;
|
||||
}
|
||||
|
||||
//cout << L << endl;
|
||||
//cout << colour << endl;
|
||||
//return vec3(0, 0, 0);
|
||||
return colour;
|
||||
}
|
||||
} else {
|
||||
return skybox(r);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int width = 3840;
|
||||
int height = 1920;
|
||||
srand(time(NULL));
|
||||
|
||||
//camera and projection plane
|
||||
vec3 lower_left_corner(-2, -1, -1);
|
||||
vec3 origin(0, 0, 0);
|
||||
vec3 horizontal(4, 0, 0);
|
||||
vec3 vertical(0, 2, 0);
|
||||
|
||||
vec3 colorlist[8] = {vec3(0.8, 0.3, 0.3), vec3(0.3, 0.8, 0.3), vec3(0.3, 0.3, 0.8),
|
||||
vec3(0.8, 0.8, 0.3), vec3(0.3, 0.8, 0.8), vec3(0.8, 0.3, 0.8),
|
||||
vec3(0.8, 0.8, 0.8), vec3(0.3, 0.3, 0.3)};
|
||||
|
||||
//test scene with spheres
|
||||
vector<sphere> hitable_list;
|
||||
hitable_list.push_back(sphere(vec3(0, -100.5, -2), 100, vec3(1.0f, 1.0f, 1.0f), 0.0f, 0.0f)); //ground
|
||||
hitable_list.push_back(sphere(vec3(0, 0, -2), 0.5, vec3(1.0f, 1.0f, 1.0f), 0.0f, 0.9f));
|
||||
hitable_list.push_back(sphere(vec3(1, 0, -1.75), 0.5, vec3(1.0f, 1.0f, 1.0f), 0.5f, 0.0f));
|
||||
hitable_list.push_back(sphere(vec3(-1, 0, -2.25), 0.5, vec3(1.0f, 0.7f, 0.3f), 0.0f, 0.0f));
|
||||
for (int i = 0; i < 48; i++) {
|
||||
float xr = ((float)rand() / (float)(RAND_MAX)) * 6.0f - 3.0f;
|
||||
float zr = ((float)rand() / (float)(RAND_MAX)) * 3.0f - 1.5f;
|
||||
int cindex = rand() % 8;
|
||||
float rand_reflec = ((float)rand() / (float)(RAND_MAX));
|
||||
//float rand_refrac = ((float)rand() / (float)(RAND_MAX));
|
||||
hitable_list.push_back(sphere(vec3(xr, -0.4, zr - 2), 0.1, colorlist[cindex], rand_reflec, 0.0f));
|
||||
}
|
||||
|
||||
fstream file;
|
||||
file.open("ray.ppm", ios::out);
|
||||
file << "P3\n"
|
||||
<< width << " " << height << "\n255\n";
|
||||
for (int j = height - 1; j >= 0; j--) {
|
||||
cout << j << endl;
|
||||
for (int i = 0; i < width; i++) {
|
||||
//cout << j << " " << i << endl;
|
||||
float u = float(i) / float(width);
|
||||
float v = float(j) / float(height);
|
||||
ray r(origin, lower_left_corner + u * horizontal + v * vertical);
|
||||
vec3 c = trace(r, hitable_list, 0);
|
||||
|
||||
file << min(255, (int)(c.r() * 255)) << " "
|
||||
<< min(255, (int)(c.g() * 255)) << " "
|
||||
<< min(255, (int)(c.b() * 255)) << endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#ifndef RAYH
|
||||
#define RAYH
|
||||
#include "vec3.h"
|
||||
|
||||
class ray {
|
||||
public:
|
||||
ray() {}
|
||||
ray(const vec3& a, const vec3& b) {
|
||||
O = a;
|
||||
D = b;
|
||||
}
|
||||
vec3 origin() const { return O; }
|
||||
vec3 direction() const { return D; }
|
||||
inline vec3 point_at_parameter(float t) const {
|
||||
return vec3(D * t + O);
|
||||
}
|
||||
|
||||
vec3 O; //center(origin) point
|
||||
vec3 D; //direction vector
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,98 @@
|
||||
//=================================================================================================
|
||||
// Written in 2016 by Peter Shirley <ptrshrl@gmail.com>
|
||||
//
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright and related and
|
||||
// neighboring rights to this software to the public domain worldwide. This software is distributed
|
||||
// without any warranty.
|
||||
//
|
||||
// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along
|
||||
// with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
//==================================================================================================
|
||||
|
||||
#ifndef VEC3H
|
||||
#define VEC3H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
class vec3 {
|
||||
public:
|
||||
vec3() {}
|
||||
vec3(float e0, float e1, float e2) {
|
||||
e[0] = e0;
|
||||
e[1] = e1;
|
||||
e[2] = e2;
|
||||
}
|
||||
vec3(const vec3 &v2){
|
||||
this->e[0] = v2.e[0];
|
||||
this->e[1] = v2.e[1];
|
||||
this->e[2] = v2.e[2];
|
||||
}
|
||||
float x() const { return e[0]; }
|
||||
float y() const { return e[1]; }
|
||||
float z() const { return e[2]; }
|
||||
float r() const { return e[0]; }
|
||||
float g() const { return e[1]; }
|
||||
float b() const { return e[2]; }
|
||||
|
||||
inline vec3 operator+(const vec3 &v2) const { return vec3(x() + v2.x(), y() + v2.y(), z() + v2.z()); }
|
||||
inline void operator+=(const vec3 &v2) { e[0] = x() + v2.x(), e[1] = y() + v2.y(), e[2] = z() + v2.z(); }
|
||||
inline vec3 operator-(const vec3 &v2) const { return vec3(x() - v2.x(), y() - v2.y(), z() - v2.z()); }
|
||||
inline void operator-=(const vec3 &v2) { e[0] = x() - v2.x(), e[1] = y() - v2.y(), e[2] = z() - v2.z(); }
|
||||
|
||||
inline vec3 operator*(const float t) const { return vec3(x() * t, y() * t, z() * t); }
|
||||
inline void operator*=(const float t) { e[0] = x() * t, e[1] = y() * t, e[2] = z() * t; }
|
||||
inline vec3 operator/(const float t) const { return vec3(x() / t, y() / t, z() / t); }
|
||||
inline void operator/=(const float t) { e[0] = x() / t, e[1] = y() / t, e[2] = z() / t; }
|
||||
|
||||
inline bool operator==(const vec3 &v2) const {
|
||||
if(this->x() == v2.x() && this->y() == v2.y() && this->z() == v2.z()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline float length() const { return sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]); }
|
||||
inline float squared_length() const { return e[0] * e[0] + e[1] * e[1] + e[2] * e[2]; }
|
||||
inline void make_unit_vector() {
|
||||
float len = length();
|
||||
e[0] = e[0] / len;
|
||||
e[1] = e[1] / len;
|
||||
e[2] = e[2] / len;
|
||||
}
|
||||
|
||||
float e[3];
|
||||
};
|
||||
|
||||
inline vec3 operator*(const float t, const vec3 &v) {
|
||||
return vec3(v.x() * t, v.y() * t, v.z() * t);
|
||||
}
|
||||
|
||||
/*
|
||||
for color calculation
|
||||
*/
|
||||
inline vec3 operator*(const vec3 &v1, const vec3 &v2) {
|
||||
return vec3(v1.e[0] * v2.e[0], v1.e[1] * v2.e[1], v1.e[2] * v2.e[2]);
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, const vec3 &t) {
|
||||
os << "( " << t.x() << " , " << t.y() << " , " << t.z() << " )";
|
||||
return os;
|
||||
}
|
||||
|
||||
inline float dot(const vec3 &v1, const vec3 &v2) {
|
||||
return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
|
||||
}
|
||||
|
||||
inline vec3 cross(const vec3 &v1, const vec3 &v2) {
|
||||
return vec3(v1.y() * v2.z() - v1.z() * v2.y(),
|
||||
v1.x() * v2.z() - v1.z() * v2.x(),
|
||||
v1.x() * v2.y() - v1.y() * v2.x());
|
||||
}
|
||||
|
||||
inline vec3 unit_vector(vec3 v) {
|
||||
return v / v.length();
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in new issue