Completed
Push — master ( 5f3088...bfb206 )
by Marko
02:40
created

Material   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 24
lcom 1
cbo 2
dl 0
loc 194
ccs 52
cts 52
cp 1
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getScripts() 0 4 1
A hasDOMAttributes() 0 8 2
C removeDefaultDOMAttributes() 0 23 7
C getDOMAttributes() 0 27 7
A shader() 0 13 3
A opacity() 0 4 1
A transparent() 0 4 2
A side() 0 4 1
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\{
27
    ComponentInterface,
28
    ShaderInterface
29
};
30
use \AframeVR\Core\Exceptions\BadShaderCallException;
31
use \DOMAttr;
32
33
class Material implements ComponentInterface
34
{
35
36
    private $shaderObj;
37
38
    /**
39
     * Whether depth testing is enabled when rendering the material.
40
     *
41
     * @var string true
42
     */
43
    protected $depthTest = 'true';
44
45
    /**
46
     * Extent of transparency.
47
     * If the transparent property is not true,
48
     * then the material will remain opaque and opacity will only affect color.
49
     *
50
     * @var float 1.0
51
     */
52
    protected $opacity = 1.0;
53
54
    /**
55
     * Whether material is transparent.
56
     * Transparent entities are rendered after non-transparent entities.
57
     *
58
     * @var string false
59
     */
60
    protected $transparent = 'false';
61
62
    /**
63
     * Which sides of the mesh to render.
64
     * Can be one of front, back, or double.
65
     *
66
     * @var string front
67
     */
68
    protected $side = 'front';
69
70
    /**
71
     * To set a texture using one of the built-in shading models, specify the src property.
72
     *
73
     * src can be a selector to either an <img> or <video> element:
74
     */
75
    protected $src = false;
76
77
    /**
78
     * Get Component scripts
79
     *
80
     * {@inheritdoc}
81
     *
82
     * @return array
83
     */
84 1
    public function getScripts(): array
85
    {
86 1
        return array();
87
    }
88
89
    /**
90
     * Does component have DOM Atributes
91
     *
92
     * {@inheritdoc}
93
     *
94
     * @return bool
95
     */
96 2
    public function hasDOMAttributes(): bool
97
    {
98 2
        $this_attributes = get_object_vars($this);
99 2
        $shader_attributes = is_object($this->shaderObj) ? get_object_vars($this->shaderObj) : [];
100 2
        $attributes = array_merge($this_attributes, $shader_attributes);
101 2
        unset($attributes['shaderObj']);
102 2
        return ! empty($attributes);
103
    }
104
105
    /**
106
     * Remove default DOMElement Attributes which are not required
107
     *
108
     * @return void
109
     */
110 2
    public function removeDefaultDOMAttributes()
111
    {
112
        $defaults = array(
113 2
            'depthTest' => 'true',
114
            'opacity' => 1.0,
115
            'transparent' => 'false',
116
            'side' => 'front'
117
        );
118
        
119
        $ignore = array(
120
            'shaderObj'
121 2
        );
122
        
123 2
        foreach (get_object_vars($this) as $name => $value) {
124 2
            if ((empty($value) || (array_key_exists($name, $defaults) && $value === $defaults[$name])) && ! in_array($name, $ignore))
125 2
                unset($this->$name);
126
        }
127
        
128
        /* Remove defaults from current shader */
129 2
        if ($this->shaderObj instanceof ShaderInterface) {
130 1
            $this->shaderObj->removeDefaultDOMAttributes();
131
        }
132 2
    }
133
134
    /**
135
     * Get DOMAttr for the entity
136
     *
137
     * @return DOMAttr
138
     */
139 1
    public function getDOMAttributes(): DOMAttr
140
    {
141 1
        $attributes = [];
142 1
        $material = [];
143 1
        $material['depthTest'] = $this->depthTest ?? null;
144 1
        $material['opacity'] = $this->opacity ?? null;
145 1
        $material['transparent'] = $this->transparent ?? null;
146 1
        $material['side'] = $this->side ?? null;
147
        
148 1
        foreach ($material as $key => $val) {
149 1
            if (empty($val) || ! property_exists($this, $key))
150 1
                unset($material[$key]);
151
        }
152 1
        if (! empty($material)) {
153 1
            $material_format = implode(': %s; ', array_keys($material)) . ': %s;';
154 1
            $attributes[] = vsprintf($material_format, array_values($material));
155
        }
156
        
157
        /* Load shader if not loaded yet */
158 1
        if (is_object($this->shaderObj)) {
159 1
            $shader_format = implode(': %s; ', array_keys(get_object_vars($this->shaderObj))) . ': %s;';
160 1
            $attributes[] = vsprintf($shader_format, array_values(get_object_vars($this->shaderObj)));
161
        }
162
        
163 1
        $format = count($attributes) === 1 ? '%s' : '%s %s';
164 1
        return new \DOMAttr('material', vsprintf($format, $attributes));
165
    }
166
167
    /**
168
     * Which shader or shading model to use.
169
     * Defaults to the built-in standard shading model.
170
     * Can be set to the built-in flat shading model or to a registered custom shader
171
     *
172
     * @var string standard
173
     * @return ShaderInterface|null
0 ignored issues
show
Documentation introduced by
Should the return type not be object|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
174
     */
175 12
    public function shader(string $shader = 'standard')
176
    {
177 12
        if ($this->shaderObj instanceof ShaderInterface)
178 2
            return $this->shaderObj;
179
        
180 12
        $shader = sprintf('\AframeVR\Core\Shaders\%s', ucfirst($shader));
181 12
        if (class_exists($shader)) {
182 11
            $this->shaderObj = new $shader();
183
        } else {
184 1
            throw new BadShaderCallException($shader);
185
        }
186 11
        return $this->shaderObj ?? null;
187
    }
188
189
    /**
190
     * opacity
191
     *
192
     * Extent of transparency. If the transparent property is not true,
193
     * then the material will remain opaque and opacity will only affect color.
194
     *
195
     * @param float $opacity            
196
     */
197 8
    public function opacity(float $opacity = 1.0)
198
    {
199 8
        $this->opacity = $opacity;
200 8
    }
201
202
    /**
203
     * transparent
204
     *
205
     * Whether material is transparent. Transparent entities are rendered after non-transparent entities.
206
     *
207
     * @param string $transparent            
0 ignored issues
show
Documentation introduced by
Should the type for parameter $transparent not be boolean|string?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
208
     */
209 7
    public function transparent(bool $transparent = false)
210
    {
211 7
        $this->transparent = $transparent ? 'true' : 'false';
212 7
    }
213
214
    /**
215
     * side
216
     *
217
     * Which sides of the mesh to render. Can be one of front, back, or double
218
     *
219
     * @param string $side            
220
     * @return EntityInterface
0 ignored issues
show
Documentation introduced by
Should the return type not be EntityInterface|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
221
     */
222 1
    public function side(string $side = 'front')
223
    {
224 1
        $this->side = $side;
225 1
    }
226
}
227