-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMaterial.cpp
140 lines (125 loc) · 4.87 KB
/
Material.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//
// Created by rthier on 2016.04.25..
//
#define DEBUG 1
#include "Material.h"
#include "ObjCommon.h" /* OBJ_DELIMITER */
#include <cstring> /* strtok_r, strdup */
#include <cstdlib>
#include "objmasterlog.h"
#include "wincompat.h" // msvc hax
namespace ObjMaster {
// Helper functions to see if a string is a prefix of an other or not...
bool Material::isPrefixOf(std::string a, const char* b){
std::string bStr = std::string(b);
return isPrefixOf(a, bStr);
}
bool Material::isPrefixOf(std::string a, std::string b){
if (a.compare(0, b.length(), b) == 0){
return true;
} else {
return false;
}
}
// Private helper method to fetch rgb values
std::vector<float> Material::fetchRGBParam(std::string &mtlLine) {
// Tokenize the string
char *copy = strdup(mtlLine.c_str());
char *savePtr;
char *key = strtok_r(copy, OBJ_DELIMITER, &savePtr);
char *rStr = strtok_r(nullptr, OBJ_DELIMITER, &savePtr);
char *gStr = strtok_r(nullptr, OBJ_DELIMITER, &savePtr);
char *bStr = strtok_r(nullptr, OBJ_DELIMITER, &savePtr);
// Convert to float values
float r = (float)atof(rStr);
float g = (float)atof(gStr);
float b = (float)atof(bStr);
// This should be after atofs as the tokenizer refers to memory in the copy!
free(copy); // strtok modifies the string so we copied it above...
// Return created vector
return std::vector<float> {r, g, b};
}
// Private helper method to fetch a string parameter
std::string Material::fetchStringParam(std::string &mtlLine) {
// Find delimiter
std::size_t pos = mtlLine.find(OBJ_DELIMITER);
// Return part of string after the first delimiter
return mtlLine.substr(pos + 1);
}
Material::Material(const std::string materialName,
std::vector <std::string> descriptorLineFields) : name{materialName} {
// Temporal variables
std::vector <float> ka, kd, ks;
std::string map_ka, map_kd, map_ks, map_bump;
// Try parsing the descriptor lines collected for the material
for (auto &mtlLine : descriptorLineFields) {
#ifdef DEBUG
OMLOGD("Parsing line: %s", mtlLine.c_str());
#endif
// Color descriptors
if (mtlLine.length() > 1 && mtlLine[0] == 'K') {
#ifdef DEBUG
OMLOGD("Color descriptor candidate line: %s", mtlLine.c_str());
#endif
if (mtlLine[1] == 'a') {
// Ka
ka = fetchRGBParam(mtlLine);
enabledFields[F_KA] = true;
continue;
}
if (mtlLine[1] == 'd') {
// Kd
kd = fetchRGBParam(mtlLine);
enabledFields[F_KD] = true;
continue;
}
if (mtlLine[1] == 's') {
// Ks
ks = fetchRGBParam(mtlLine);
enabledFields[F_KS] = true;
continue;
}
}
// Texture map descriptors
// First do a fast check on the first letter!
if (mtlLine.length() > 0 && (mtlLine[0] == 'm' || mtlLine[0] == 'b')) {
#ifdef DEBUG
OMLOGD("Texture descriptor candidate line: %s", mtlLine.c_str());
#endif
if (mtlLine.compare(0, std::string("map_Ka").length(), std::string("map_Ka")) == 0) {
// map_Ka
map_ka = fetchStringParam(mtlLine);
enabledFields[F_MAP_KA] = true;
continue;
}
if (mtlLine.compare(0, std::string("map_Kd").length(), std::string("map_Kd")) == 0) {
// map_Kd
map_kd = fetchStringParam(mtlLine);
enabledFields[F_MAP_KD] = true;
continue;
}
if (mtlLine.compare(0, std::string("map_Ks").length(), std::string("map_Ks")) == 0) {
// map_Ks
map_ks = fetchStringParam(mtlLine);
enabledFields[F_MAP_KS] = true;
continue;
}
if ((mtlLine.compare(0, std::string("map_bump").length(), std::string("map_bump")) == 0) ||
(mtlLine.compare(0, std::string("map_Bump").length(), std::string("map_Bump")) == 0)) {
// map_bump OR map_Bump
map_bump = fetchStringParam(mtlLine);
enabledFields[F_MAP_BUMP] = true;
continue;
}
}
}
// Save the found data
this->ka = ka;
this->kd = kd;
this->ks = ks;
this->map_ka = map_ka;
this->map_kd = map_kd;
this->map_ks = map_ks;
this->map_bump = map_bump;
}
}