1 // Copyright 2009-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3
4 // ospray
5 #include "Material.h"
6 #include "common/Util.h"
7 #include "texture/Texture2D.h"
8
9 #include "texture/TextureParam_ispc.h"
10
11 namespace ospray {
12
13 static FactoryMap<Material> g_materialsMap;
14
15 // Material definitions ///////////////////////////////////////////////////////
16
17 Material::Material()
18 {
19 managedObjectType = OSP_MATERIAL;
20 }
21
22 Material *Material::createInstance(
23 const char */*ignored*/, const char *_material_type)
24 {
25 std::string name = _material_type;
26 return createInstanceHelper(name, g_materialsMap[name]);
27 }
28
29 void Material::registerType(const char *name, FactoryFcn<Material> f)
30 {
31 g_materialsMap[name] = f;
32 }
33
34 std::string Material::toString() const
35 {
36 return "ospray::Material";
37 }
38
39 void Material::commit() {}
40
41 ispc::TextureParam Material::getTextureParam(const char *texture_name)
numJobs(const int spp,int accumID)42 {
43 // Get texture pointer
44 Texture2D *ptr = (Texture2D *)getParamObject(texture_name);
45
46 // Get 2D transformation if exists
47 int transformFlags = ispc::TRANSFORM_FLAG_NONE;
48 affine2f xfm2f = affine2f(one);
49 utility::Optional<affine2f> xform2f = getTextureTransform2f(texture_name);
50 if (xform2f.has_value()) {
51 xfm2f = xform2f.value();
52 transformFlags |= ispc::TRANSFORM_FLAG_2D;
53 }
54
55 // Get 3D transformation if exists
56 affine3f xfm3f = affine3f(one);
57 auto xform3f =
58 getOptParam<affine3f>((std::string(texture_name) + ".transform").c_str());
59 if (xform3f.has_value()) {
60 xfm3f = xform3f.value();
61 transformFlags |= ispc::TRANSFORM_FLAG_3D;
62 }
63
64 // Initialize ISPC structure
65 ispc::TextureParam param;
66 TextureParam_set(¶m,
67 ptr ? ptr->getIE() : nullptr,
68 (ispc::TransformFlags)transformFlags,
69 (const ispc::AffineSpace2f &)xfm2f,
70 (const ispc::AffineSpace3f &)xfm3f);
71
72 // Done
73 return param;
74 }
75
76 MaterialParam1f Material::getMaterialParam1f(
77 const char *name, float valIfNotFound)
78 {
79 const std::string mapName = "map_" + std::string(name);
80 MaterialParam1f param;
81 param.tex = getTextureParam(mapName.c_str());
82 param.rot = ((linear2f *)(¶m.tex.xform2f.l))->orthogonal().transposed();
83 param.factor = getParam<float>(name, param.tex.ptr ? 1.f : valIfNotFound);
84 return param;
85 }
86
87 MaterialParam3f Material::getMaterialParam3f(
88 const char *name, vec3f valIfNotFound)
89 {
90 const std::string mapName = "map_" + std::string(name);
91 MaterialParam3f param;
92 param.tex = getTextureParam(mapName.c_str());
93 param.rot = ((linear2f *)(¶m.tex.xform2f.l))->orthogonal().transposed();
94 param.factor =
95 getParam<vec3f>(name, param.tex.ptr ? vec3f(1.f) : valIfNotFound);
96 return param;
97 }
98
99 utility::Optional<affine2f> Material::getTextureTransform2f(
100 const char *_texname)
101 {
102 std::string texname(_texname);
103 texname += ".";
104 utility::Optional<affine2f> xform;
105
106 // Apply translation
107 const utility::Optional<vec2f> translation =
108 getOptParam<vec2f>((texname + "translation").c_str());
109 if (translation.has_value())
110 xform = affine2f::translate(-translation.value());
111
112 // Apply scale
113 const utility::Optional<vec2f> scale =
114 getOptParam<vec2f>((texname + "scale").c_str());
115 if (scale.has_value()) {
116 xform = xform.value_or(affine2f(one)) * affine2f::translate(vec2f(0.5f));
117 xform = *xform * affine2f::scale(rcp(scale.value()));
118 xform = *xform * affine2f::translate(vec2f(-0.5f));
119 }
120
121 // Apply rotation
122 const utility::Optional<float> rotation =
123 getOptParam<float>((texname + "rotation").c_str());
124 if (rotation.has_value()) {
125 xform = xform.value_or(affine2f(one)) * affine2f::translate(vec2f(0.5f));
126 xform = *xform * affine2f::rotate(-deg2rad(rotation.value()));
127 xform = *xform * affine2f::translate(vec2f(-0.5f));
128 }
129
130 // Apply complete transformation
131 const utility::Optional<linear2f> transf =
132 getOptParam<linear2f>((texname + "transform").c_str());
133 if (transf.has_value())
134 xform = xform.value_or(affine2f(one)) * affine2f(transf.value());
135 const utility::Optional<vec4f> transf4 = // legacy / backwards compatible
136 getOptParam<vec4f>((texname + "transform").c_str());
137 if (transf4.has_value()) {
138 const linear2f transform = (const linear2f &)transf4.value();
139 xform = xform.value_or(affine2f(one)) * affine2f(transform);
140 }
141
142 // Return optional transformation
143 return xform;
144 }
145
146 OSPTYPEFOR_DEFINITION(Material *);
147
148 } // namespace ospray
149