Visual Computing Library  devel
Loading...
Searching...
No Matches
material.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_IO_MESH_OBJ_MATERIAL_H
24#define VCL_IO_MESH_OBJ_MATERIAL_H
25
26#include <vclib/space/core.h>
27
28namespace vcl::detail {
29
37class ObjMaterial
38{
39 inline static const Point3f Ka_DEFAULT = {0.2f, 0.2f, 0.2f}; // ambient;
40 inline static const Point3f Kd_DEFAULT = {1.0f, 1.0f, 1.0f}; // diffuse;
41 inline static const Point3f Ks_DEFAULT = {1.0f, 1.0f, 1.0f}; // specular;
42 inline static const Point3f Ke_DEFAULT = {0.0f, 0.0f, 0.0f}; // emissive;
43
44 inline static const float d_DEFAULT = 1.0f; // alpha
45 inline static const int illum_DEFAULT = 2; // specular illumination
46 inline static const float Ns_DEFAULT = 0.f;
47
48public:
49 // id of the material in the mesh, used when loading materials
50 uint matId = UINT_NULL;
51 std::string matName;
52
53 Point3f Ka = Ka_DEFAULT; // ambient
54 Point3f Kd = Kd_DEFAULT; // diffuse
55 Point3f Ks = Ks_DEFAULT; // specular
56 Point3f Ke = Ke_DEFAULT; // emissive
57
58 float d = d_DEFAULT; // alpha
59
60 int illum = illum_DEFAULT; // specular illumination
61 float Ns = Ns_DEFAULT;
62
63 std::string map_Kd; // filename texture
64 std::string map_Ke; // filename emissive map
65 std::string map_bump; // filename bump map
66
67 ObjMaterial() = default;
68
69 ObjMaterial(const Material& mat, uint id)
70 {
71 using enum Material::TextureType;
72
73 matId = id;
74 matName = mat.name();
75
76 Kd.x() = mat.baseColor().redF();
77 Kd.y() = mat.baseColor().greenF();
78 Kd.z() = mat.baseColor().blueF();
79 Ns = std::pow(1.0f - mat.roughness(), 2) * 1000.f;
80 if (mat.alphaMode() == Material::AlphaMode::ALPHA_BLEND) {
81 d = mat.baseColor().alphaF();
82 }
83
84 Ke.x() = mat.emissiveColor().redF();
85 Ke.y() = mat.emissiveColor().greenF();
86 Ke.z() = mat.emissiveColor().blueF();
87
88 map_Kd = mat.baseColorTextureDescriptor().path();
89 map_Ke = mat.textureDescriptor(EMISSIVE).path();
90 // map_bump = mat.textureDescriptor(NORMAL).path();
91 }
92
102 Material toMaterial()
103 {
104 using enum Material::TextureType;
105
106 Material m;
107 m.name() = matName;
108 m.baseColor() =
109 vcl::Color(Kd.x() * 255, Kd.y() * 255, Kd.z() * 255, 255);
110
111 float ns = std::clamp(Ns, 0.f, 1000.f);
112 m.roughness() = 1.0f - std::sqrt(ns) / std::sqrt(1000.f);
113
114 if (d < 1.0) {
115 m.baseColor().alpha() = d * 255;
116 m.alphaMode() = Material::AlphaMode::ALPHA_BLEND;
117 }
118
119 m.metallic() = 0.0f; // obj materials are non-metallic;
120
121 m.emissiveColor() =
122 vcl::Color(Ke.x() * 255, Ke.y() * 255, Ke.z() * 255, 255);
123
124 if (!map_Kd.empty()) {
125 m.baseColorTextureDescriptor().path() = map_Kd;
126 }
127 if (!map_Ke.empty()) {
128 m.textureDescriptor(EMISSIVE).path() = map_Ke;
129 }
130 // if (!map_bump.empty()) {
131 // m.textureDescriptor(NORMAL).path() = map_bump;
132 // }
133
134 return m;
135 }
136
137 bool isValid() const { return matId != UINT_NULL; }
138
139 Color color() const
140 {
141 return Color(Kd.x() * 255, Kd.y() * 255, Kd.z() * 255, d * 255);
142 }
143
144 const std::string& texture() const { return map_Kd; }
145
146 uint textureId() const { return matId; }
147
148 bool operator==(const ObjMaterial& m) const = default;
149
150 friend inline std::ostream& operator<<(
151 std::ostream& out,
152 const ObjMaterial& m);
153};
154
155inline std::ostream& operator<<(std::ostream& out, const ObjMaterial& m)
156{
157 if (m.Ka != m.Ka_DEFAULT)
158 out << "Ka " << m.Ka.x() << " " << m.Ka.y() << " " << m.Ka.z()
159 << std::endl;
160
161 if (m.Kd != m.Kd_DEFAULT)
162 out << "Kd " << m.Kd.x() << " " << m.Kd.y() << " " << m.Kd.z()
163 << std::endl;
164
165 if (m.Ks != m.Ks_DEFAULT)
166 out << "Ks " << m.Ks.x() << " " << m.Ks.y() << " " << m.Ks.z()
167 << std::endl;
168
169 if (m.Ke != m.Ke_DEFAULT)
170 out << "Ke " << m.Ke.x() << " " << m.Ke.y() << " " << m.Ke.z()
171 << std::endl;
172
173 if (m.d != m.d_DEFAULT)
174 out << "d " << m.d << std::endl;
175
176 if (m.illum != m.illum_DEFAULT)
177 out << "illum " << m.illum << std::endl;
178
179 if (m.Ns != m.Ns_DEFAULT)
180 out << "Ns " << m.Ns << std::endl;
181
182 if (!m.map_Kd.empty()) {
183 out << "map_Kd " << m.map_Kd << std::endl;
184 }
185
186 if (m.map_Ke.empty()) {
187 out << "map_Ke " << m.map_Ke << std::endl;
188 }
189
190 // if (m.map_bump.empty()) {
191 // out << "map_bump " << m.map_bump << std::endl;
192 // }
193
194 return out;
195}
196
197} // namespace vcl::detail
198
199#endif // VCL_IO_MESH_OBJ_MATERIAL_H
The Color class represents a 32 bit color.
Definition color.h:48
TextureType
Defines the types of textures used in the PBR material model.
Definition material.h:62
constexpr uint UINT_NULL
The UINT_NULL value represent a null value of uint that is the maximum value that can be represented ...
Definition base.h:48
Point3< float > Point3f
A convenience alias for a 3-dimensional Point with floating-point components.
Definition point.h:768