ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
GradientMaterial.tpp
Go to the documentation of this file.
1#pragma once
2
3
4template<size_t colorCount>
5GradientMaterial<colorCount>::GradientMaterial(RGBColor* rgbColors, float gradientPeriod, bool isRadial, bool isStepped) {
6 this->gradientPeriod = gradientPeriod;
7 this->isRadial = isRadial;
8 this->isStepped = isStepped;
9 this->baseRGBColors = rgbColors;
10
11 UpdateGradient(rgbColors);
12}
13
14template<size_t colorCount>
15void GradientMaterial<colorCount>::UpdateGradient(RGBColor* rgbColors) {
16 for (uint8_t i = 0; i < colorCount; i++) {
17 this->rgbColors[i] = rgbColors[i];
18 }
19}
20
21template<size_t colorCount>
22void GradientMaterial<colorCount>::SetPositionOffset(Vector2D positionOffset) {
23 this->positionOffset = positionOffset;
24}
25
26template<size_t colorCount>
27void GradientMaterial<colorCount>::SetRotationOffset(Vector2D rotationOffset) {
28 this->rotationOffset = rotationOffset;
29}
30
31template<size_t colorCount>
32void GradientMaterial<colorCount>::SetRotationAngle(float rotationAngle) {
33 this->rotationAngle = rotationAngle;
34}
35
36template<size_t colorCount>
37void GradientMaterial<colorCount>::SetGradientPeriod(float gradientPeriod) {
38 this->gradientPeriod = gradientPeriod;
39}
40
41template<size_t colorCount>
42void GradientMaterial<colorCount>::GradientShift(float ratio) {
43 this->gradientShift = ratio;
44}
45
46template<size_t colorCount>
47void GradientMaterial<colorCount>::HueShift(float hueDeg) {
48 for (uint8_t i = 0; i < colorCount; i++) {
49 rgbColors[i] = baseRGBColors[i].HueShift(hueDeg);
50 }
51}
52
53template<size_t colorCount>
54void GradientMaterial<colorCount>::UpdateRGB() {
55 for (uint8_t i = 0; i < colorCount; i++) {
56 rgbColors[i] = baseRGBColors[i];
57 }
58}
59
60template<size_t colorCount>
61RGBColor GradientMaterial<colorCount>::GetRGB(const Vector3D& position, const Vector3D& normal, const Vector3D& uvw) {
62 Vector3D positionL = position;
63
64 if (rotationAngle != 0) {
65 Quaternion temp = Rotation(EulerAngles(Vector3D(0, 0, rotationAngle), EulerConstants::EulerOrderXYZS)).GetQuaternion();
66
67 positionL = temp.RotateVector(positionL);
68 }
69
70 float pos = 0;
71 positionL = positionL - Vector3D(positionOffset.X, positionOffset.Y, 0);
72 positionL = positionL + Vector3D(gradientShift * gradientPeriod, 0, 0);
73
74 if (isRadial) {
75 pos = sqrtf(positionL.X * positionL.X + positionL.Y * positionL.Y);
76 pos = fabs(fmodf(pos, gradientPeriod));
77 }
78 else {
79 // from x position, fit into bucket ratio
80 pos = fabs(fmodf(positionL.X, gradientPeriod));
81 }
82
83 // map from modulo'd x value to color count minimum
84 float ratio = Mathematics::Map(pos, 0.0f, gradientPeriod, 0.0f, float(colorCount));
85 uint8_t startBox = floor(ratio);
86 uint8_t endBox = startBox + 1 >= (uint8_t)colorCount ? 0 : startBox + 1;
87
88 RGBColor rgb;
89
90 if (isStepped) {
91 rgb = rgbColors[startBox];
92 }
93 else {
94 float mu = Mathematics::Map(ratio, float(startBox), float(startBox + 1), 0.0f, 1.0f); // calculate mu between boxes
95
96 rgb = RGBColor::InterpolateColors(rgbColors[startBox], rgbColors[endBox], mu);
97 }
98
99 return rgb;
100}