Completed
Push — master ( ce557b...46a40a )
by Marko
02:10
created

Material::getDOMAttributes()   C

Complexity

Conditions 7
Paths 24

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 0
cts 17
cp 0
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 18
nc 24
nop 0
crap 56
1
<?php
2
/** @formatter:off
3
 * ******************************************************************
4
 * Created by   Marko Kungla on Jun 21, 2016 - 1:43:40 AM
5
 * Contact      [email protected]
6
 * @copyright   2016 Marko Kungla - https://github.com/mkungla
7
 * @license     The MIT License (MIT)
8
 * 
9
 * @category       AframeVR
10
 * @package        aframe-php
11
 * 
12
 * Lang         PHP (php version >= 7)
13
 * Encoding     UTF-8
14
 * File         Material.php
15
 * Code format  PSR-2 and 12
16
 * @link        https://github.com/mkungla/aframe-php
17
 ^ @issues      https://github.com/mkungla/aframe-php/issues
18
 * ********************************************************************
19
 * Contributors:
20
 * @author Marko Kungla <[email protected]>
21
 * ********************************************************************
22
 * Comments:
23
 * @formatter:on */
24
namespace AframeVR\Components;
25
26
use \AframeVR\Interfaces\ComponentInterface;
27
use \AframeVR\Interfaces\ShaderInterface;
28
use \AframeVR\Core\Exceptions\BadShaderCallException;
29
use \DOMAttr;
30
31
class Material implements ComponentInterface
32
{
33
34
    private $shaderObj;
35
36
    /**
37
     * Whether depth testing is enabled when rendering the material.
38
     *
39
     * @var string true
40
     */
41
    protected $depthTest = 'true';
42
43
    /**
44
     * Extent of transparency.
45
     * If the transparent property is not true,
46
     * then the material will remain opaque and opacity will only affect color.
47
     *
48
     * @var float 1.0
49
     */
50
    protected $opacity = 1.0;
51
52
    /**
53
     * Whether material is transparent.
54
     * Transparent entities are rendered after non-transparent entities.
55
     *
56
     * @var string false
57
     */
58
    protected $transparent = 'false';
59
60
    /**
61
     * Which sides of the mesh to render.
62
     * Can be one of front, back, or double.
63
     *
64
     * @var string front
65
     */
66
    protected $side = 'front';
67
68
    /**
69
     * To set a texture using one of the built-in shading models, specify the src property.
70
     *
71
     * src can be a selector to either an <img> or <video> element:
72
     */
73
    protected $src = false;
74
75
    /**
76
     * Get Component scripts
77
     *
78
     * {@inheritdoc}
79
     *
80
     * @return array
81
     */
82
    public function getScripts(): array
83
    {
84
        return array();
85
    }
86
87
    /**
88
     * Does component have DOM Atributes
89
     *
90
     * {@inheritdoc}
91
     *
92
     * @return bool
93
     */
94 1
    public function hasDOMAttributes(): bool
95
    {
96 1
        $this_attributes = get_object_vars($this);
97 1
        $shader_attributes = is_object($this->shaderObj) ? get_object_vars($this->shaderObj) : [];
98 1
        $attributes = array_merge($this_attributes, $shader_attributes);
99 1
        unset($attributes['shaderObj']);
100 1
        return !empty($attributes);
101
    }
102
103
    /**
104
     * Remove default DOMElement Attributes which are not required
105
     *
106
     * @return void
107
     */
108 1
    public function removeDefaultDOMAttributes()
109
    {
110
        $defaults = array(
111 1
            'depthTest' => 'true',
112
            'opacity' => 1.0,
113
            'transparent' => 'false',
114
            'side' => 'front'
115
        );
116
        
117
        $ignore = array(
118
            'shaderObj'
119 1
        );
120
        
121 1
        foreach (get_object_vars($this) as $name => $value) {
122 1
            if ((empty($value) || (array_key_exists($name, $defaults) && $value === $defaults[$name])) && ! in_array($name, $ignore))
123 1
                unset($this->$name);
124
        }
125
        
126
        /* Remove defaults from current shader */
127 1
        if(is_object($this->shaderObj))
128
            $this->shaderObj->removeDefaultDOMAttributes();
129 1
    }
130
131
    /**
132
     * Get DOMAttr for the entity
133
     *
134
     * @return DOMAttr
135
     */
136
    public function getDOMAttributes(): DOMAttr
137
    {
138
        $attributes = [];
139
        $material = array(
140
            'depthTest' => $this->depthTest ?? null,
141
            'opacity' => $this->opacity ?? null,
142
            'transparent' => $this->transparent ?? null,
143
            'side' => $this->side ?? null
144
        );
145
        
146
        foreach ($material as $key => $val) {
147
            if (empty($val) || ! property_exists($key, $this))
148
                unset($material[$key]);
149
        }
150
        if (! empty($material)) {
151
            $material_format = implode(': %s; ', array_keys($material)) . ': %s;';
152
            $attributes[] = vsprintf($material_format, array_values($material));
153
        }
154
        
155
        /* Load shader if not loaded yet */
156
        if(is_object($this->shaderObj)) {
157
            $shader_format = implode(': %s; ', array_keys(get_object_vars($this->shaderObj))) . ': %s;';
158
            $attributes[] = vsprintf($shader_format, array_values(get_object_vars($this->shaderObj)));
159
        }
160
       
161
        
162
        $format = count($attributes) === 1 ? '%s' : '%s %s';
163
        return new \DOMAttr('material', vsprintf($format, $attributes));
164
    }
165
166
    /**
167
     * Which shader or shading model to use.
168
     * Defaults to the built-in standard shading model.
169
     * Can be set to the built-in flat shading model or to a registered custom shader
170
     *
171
     * @var string standard
172
     */
173 6
    public function shader(string $shader = 'standard')
174
    {
175 6
        if ($this->shaderObj instanceof ShaderInterface)
176
            return $this->shaderObj;
177
        
178
        try {
179 6
            $shader = sprintf('\AframeVR\Core\Shaders\%s', ucfirst($shader));
180 6
            if (class_exists($shader)) {
181 6
                $this->shaderObj = new $shader();
182
            } else {
183 6
                throw new BadShaderCallException($shader);
184
            }
185
        } catch (BadShaderCallException $e) {
186
            die($e->getMessage());
187
        }
188 6
        return $this->shaderObj;
189
    }
190
191
    /**
192
     * opacity
193
     *
194
     * Extent of transparency. If the transparent property is not true,
195
     * then the material will remain opaque and opacity will only affect color.
196
     *
197
     * @param float $opacity
198
     */
199 6
    public function opacity(float $opacity = 1.0)
200
    {
201 6
        $this->opacity = $opacity;
202 6
    }
203
204
    /**
205
     * transparent
206
     *
207
     * Whether material is transparent. Transparent entities are rendered after non-transparent entities.
208
     *
209
     * @param string $transparent            
210
     */
211 6
    public function transparent(string $transparent = 'false')
212
    {
213 6
        $this->transparent = $transparent;
214 6
    }
215
216
    /**
217
     * side
218
     *
219
     * Which sides of the mesh to render. Can be one of front, back, or double
220
     *
221
     * @param string $side            
222
     * @return EntityInterface
223
     */
224
    public function side(string $side = 'front'): EntityInterface
225
    {
226
        $this->side = $side;
227
    }
228
}
229