glitch3d 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ab2d06c3a8af4e43f252d1aa2342209c4e8b921
4
- data.tar.gz: 25ee7f24892d01b73f2bd82d6a978656c15fd87c
3
+ metadata.gz: 1793293a1331bc23dd4107bd664cb3a58c94e08f
4
+ data.tar.gz: 75032fca2f9644099ffec1691c9e9e43eff88dd1
5
5
  SHA512:
6
- metadata.gz: 266c53f8b005835192605ac3c2238f088ed61102d0efbb0c040c7f081e35c4734ab4e6bcbfd451ace3a772e131eab6a3b7ecae083f6d503dcaf9e3666c6dee72
7
- data.tar.gz: 1d4618d047a7306437c05443423df5eab85ae9eedae7bf434c28eab9db50b8ef1647577aca463a1321eddced851ebbf2a5dab905c0c36012e13988b8699d64fc
6
+ metadata.gz: 41b1e28a7a1025348d6d8238b11f5c5e7fc336967690b34cba59c037722dac80adfcab55e58c4290e18de1b9df7db9ab408300e87adab03a97e9ab0d431bed73
7
+ data.tar.gz: b5020f50d233c5c863b4a6345b2cc9042022e6ac647d23943b6faadaf2996bb343ba106b06e46930c5190e88adc8afc5510ee2cb5b0765b4984bce8ca0681341
data/README.md CHANGED
@@ -2,22 +2,13 @@
2
2
 
3
3
  By altering .obj file data you can get something like this :
4
4
 
5
- <img style="width:70%;height:70%;display:block;margin: 0 auto;" src="https://raw.githubusercontent.com/pskl/glitch3d/master/fixtures/demo.png">
5
+ <img src="https://raw.githubusercontent.com/pskl/glitch3d/master/fixtures/demo.png" width="400">
6
6
 
7
- ## Disclaimer
7
+ This gem uses the Blender Python API to produces renders headlessly.
8
8
 
9
- Work in progress. The gem is not usable at the moment.
10
- Rationale: Model data manipulation is done in ruby, while anything related to the rendering process is done in Python using the Blender API.
11
- Usage
12
- ---
13
- - `3dglitch source_file_name` (a .obj file)
9
+ ## Warning
14
10
 
15
- ## A quick note on the .obj file format
16
-
17
- - v -> represents a vertice position
18
- - f -> represents a face (contains references to vertices, can be triangle, quad...)
19
- - vt -> texture UV map
20
- - vn -> vertex normal
11
+ Setting `BLENDER_EXECUTABLE_PATH` in your environment is required.
21
12
 
22
13
  ## Installation
23
14
 
@@ -37,7 +28,12 @@ Or install it yourself as:
37
28
 
38
29
  ## Usage
39
30
 
40
- TODO: Write usage instructions here
31
+ - `glitch3d file.obj`
32
+
33
+ Options:
34
+ - `mode` : (localized|default|none)
35
+ - `shots-number` : integer representing the number of - images desired
36
+ - `quality` : (high|low)
41
37
 
42
38
  ## Development
43
39
 
@@ -53,3 +49,6 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERN
53
49
  ## License
54
50
 
55
51
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
52
+
53
+ ## TODO
54
+ - write specs
@@ -1,31 +1,40 @@
1
1
  require "glitch3d/version"
2
2
  require "glitch3d/objects/vertex"
3
3
  require "glitch3d/objects/face"
4
- require "glitch3d/strategies/default"
5
- require "glitch3d/strategies/localized"
6
- require "pry"
4
+ require 'pry'
5
+ Dir[File.dirname(__FILE__) + '/glitch3d/strategies/*.rb'].each {|file| require file }
7
6
 
8
7
  module Glitch3d
9
- VERTEX_GLITCH_ITERATION_RATIO = 0.001
8
+ VERTEX_GLITCH_ITERATION_RATIO = 0.1
10
9
  VERTEX_GLITCH_OFFSET = 1
11
10
 
12
- FACE_GLITCH_ITERATION_RATIO = 0.0
11
+ FACE_GLITCH_ITERATION_RATIO = 0.1
13
12
  FACE_GLITCH_OFFSET = 0.5
14
13
  BOUNDARY_LIMIT = 4 # Contain model within 2x2x2 cube
15
14
 
16
15
  BLENDER_EXECUTABLE_PATH = ENV['BLENDER_EXECUTABLE_PATH'].freeze
17
16
  RENDERING_SCRIPT_PATH = "lib/glitch3d/bpy/rendering.py".freeze
18
17
 
18
+ def clean_model(source_file)
19
+ self.class.include Glitch3d::None
20
+ base_file_name = source_file.gsub(/.obj/, '')
21
+ model_name = File.basename(source_file, '.obj')
22
+ target_file = base_file_name + '.obj'
23
+ create_glitched_file(glitch(read_source(source_file)), target_file, model_name)
24
+ end
25
+
19
26
  def process_model(source_file)
20
- raise 'Set Blender executable path in your env variables before using glitch3d' unless BLENDER_EXECUTABLE_PATH.present?
21
27
  args = Hash[ARGV.join(' ').scan(/--?([^=\s]+)(?:=(\S+))?/)]
28
+ return clean_model(source_file) if args["clean"]
29
+ raise 'Set Blender executable path in your env variables before using glitch3d' if BLENDER_EXECUTABLE_PATH.nil?
22
30
  self.class.include infer_strategy(args["mode"] || 'default')
23
31
  @quality = args["quality"] || 'low'
24
32
  source_file = source_file
25
33
  base_file_name = source_file.gsub(/.obj/, '')
34
+ model_name = File.basename(source_file, '.obj')
26
35
  target_file = base_file_name + '_glitched.obj'
27
- boundaries = create_glitched_file(glitch(read_source(source_file)), target_file)
28
- render(target_file, boundaries, args["shots-number"] || 6) unless args["no-render"]
36
+ create_glitched_file(glitch(read_source(source_file)), target_file, model_name)
37
+ render(target_file, args["shots-number"] || 6) unless args["no-render"]
29
38
  end
30
39
 
31
40
  def infer_strategy(mode)
@@ -90,7 +99,7 @@ module Glitch3d
90
99
  array[rand(0..array.size - 1)]
91
100
  end
92
101
 
93
- def create_glitched_file(content_hash, target_file)
102
+ def create_glitched_file(content_hash, target_file, model_name)
94
103
  boundaries = Vertex.boundaries(content_hash[:vertices])
95
104
  puts boundaries.to_s
96
105
  while rescale_needed?(boundaries)
@@ -101,22 +110,21 @@ module Glitch3d
101
110
  puts boundaries.to_s
102
111
  File.open(target_file, 'w') do |f|
103
112
  f.puts '# Data corrupted with glitch3D script'
104
- f.puts '# Boundaries: ' + boundaries.to_s
113
+ f.puts '# Boundaries: ' + boundaries.to_s
105
114
  f.puts ''
106
- f.puts 'g Glitch3D'
115
+ f.puts "g #{model_name}"
107
116
  f.puts ''
108
117
  f.puts content_hash[:vertices].map(&:to_s)
109
118
  f.puts ''
110
119
  f.puts content_hash[:faces].map(&:to_s).compact
111
120
  end
112
- boundaries
113
121
  end
114
122
 
115
123
  def rescale_needed?(boundaries)
116
124
  boundaries.flatten.map(&:abs).max.abs > BOUNDARY_LIMIT
117
125
  end
118
126
 
119
- def render(file_path, boundaries, shots_number)
127
+ def render(file_path, shots_number)
120
128
  args = [
121
129
  BLENDER_EXECUTABLE_PATH,
122
130
  '-b',
@@ -1,3 +1,9 @@
1
+ YELLOW = (1,0.7,0.1,1)
2
+
3
+ def debug():
4
+ code.interact(local=dict(globals(), **locals()))
5
+ sys.exit("Aborting execution")
6
+
1
7
  # Helper methods
2
8
  def look_at(camera_object, point):
3
9
  location_camera = camera_object.matrix_world.to_translation()
@@ -7,9 +13,8 @@ def look_at(camera_object, point):
7
13
  camera_object.rotation_euler = rot_quat.to_euler()
8
14
 
9
15
  def empty_materials():
10
- mats = bpy.data.materials
11
- for mat in mats.keys():
12
- mats.remove(mats[mat])
16
+ for material in bpy.data.materials.keys():
17
+ bpy.data.materials.remove(object.data.materials[material])
13
18
 
14
19
  def shoot(camera, model_object, filepath):
15
20
  look_at(camera, model_object)
@@ -42,21 +47,21 @@ def rand_color_vector():
42
47
  return (rand_color_value(), rand_color_value(), rand_color_value(), 1)
43
48
 
44
49
  def rand_scale():
45
- return round(random.uniform(0, 0.3), 10)
50
+ return round(random.uniform(0, 0.15), 10)
51
+
52
+ def rand_scale_vector():
53
+ return(rand_scale(), rand_scale(), rand_scale())
46
54
 
47
55
  def get_args():
48
56
  parser = argparse.ArgumentParser()
49
-
50
57
  # get all script args
51
58
  _, all_arguments = parser.parse_known_args()
52
59
  double_dash_index = all_arguments.index('--')
53
60
  script_args = all_arguments[double_dash_index + 1: ]
54
-
55
61
  # add parser rules
56
62
  parser.add_argument('-f', '--file', help="obj file to render")
57
63
  parser.add_argument('-n', '--shots-number', help="number of shots desired")
58
64
  parser.add_argument('-m', '--mode', help="quality mode: low | high")
59
-
60
65
  parsed_script_args, _ = parser.parse_known_args(script_args)
61
66
  return parsed_script_args
62
67
 
@@ -74,24 +79,51 @@ def assign_node_to_output(material, new_node):
74
79
  output_node = material.node_tree.nodes['Material Output']
75
80
  material.node_tree.links.new(new_node.outputs[0], output_node.inputs['Surface'])
76
81
 
82
+ # Returns a new Cycles material with default DiffuseBsdf node linked to output
77
83
  def create_cycles_material():
78
84
  material = bpy.data.materials.new('Object Material - ' + str(uuid.uuid1()))
79
85
  material.use_nodes = True
80
-
81
- nodes = material.node_tree.nodes
82
- new_node = nodes.new(random.choice(SHADERS))
83
-
84
- assign_node_to_output(material, new_node)
86
+ # nodes = material.node_tree.nodes
87
+ # new_node = nodes.new(random.choice(SHADERS))
88
+ # assign_node_to_output(material, new_node)
85
89
  return material
86
90
 
87
- def assign_random_texture_to_material(material):
91
+ def random_texture():
92
+ texture_path = os.path.expanduser('fixtures/textures/checkered_texture.jpg')
93
+ # new_texture = bpy.data.textures.new('ColorTex', type = 'IMAGE')
94
+ return bpy.data.images.load(texture_path)
95
+ # rand.choice()
96
+
97
+ def assign_texture_to_material(material, texture):
88
98
  assert material.use_nodes == True
99
+ # If its a default material
89
100
  bsdf_node = material.node_tree.nodes['Diffuse BSDF']
90
101
  assign_node_to_output(material, bsdf_node)
91
- texture_node = material.node_tree.nodes.new('ShaderNodeTexture')
102
+ texture_node = material.node_tree.nodes.new('ShaderNodeTexImage')
103
+ uv_node = material.node_tree.nodes.new('ShaderNodeUVMap')
104
+ # uv_node.uv_map = 'UV'
105
+ texture_node.image = texture
92
106
  material.node_tree.links.new(texture_node.outputs[0], bsdf_node.inputs[0])
93
- # code.interact(local=dict(globals(), **locals()))
94
- texture_path = os.path.expanduser('fixtures/textures/25.jpg')
95
- new_texture = bpy.data.textures.new('ColorTex', type = 'IMAGE')
96
- new_texture.image = bpy.data.images.load(texture_path)
97
- texture_node.texture = new_texture
107
+ material.node_tree.links.new(texture_node.inputs['Vector'], uv_node.outputs['UV'])
108
+
109
+ def make_object_gold(object):
110
+ material = bpy.data.materials.new('Gold Material - ' + str(uuid.uuid1()))
111
+ material.use_nodes = True
112
+ glossy_node = material.node_tree.nodes.new('ShaderNodeBsdfGlossy')
113
+ glossy_node.inputs[0].default_value = YELLOW
114
+ # roughness
115
+ glossy_node.inputs[1].default_value = 0.1
116
+ assign_node_to_output(material, glossy_node)
117
+ assign_material(object, material)
118
+
119
+ def make_object_reflector(object):
120
+ object.scale = (REFLECTOR_SCALE, REFLECTOR_SCALE, REFLECTOR_SCALE)
121
+ emissive_material = bpy.data.materials.new('Emissive Material #' + str(index))
122
+ emissive_material.use_nodes = True
123
+ emission_node = emissive_material.node_tree.nodes.new('ShaderNodeEmission')
124
+ # Set color
125
+ emission_node.inputs[0].default_value = rand_color_vector()
126
+ # Set strength
127
+ emission_node.inputs[1].default_value = REFLECTOR_STRENGTH
128
+ assign_node_to_output(emissive_material, emission_node)
129
+ assign_material(object, emissive_material)
@@ -8,7 +8,7 @@
8
8
  # 3) Create camera
9
9
  # 4) Rotate model and shoot image at each step
10
10
  #
11
- # Use `code.interact(local=dict(globals(), **locals()))` to pry into the script
11
+ # Use `debug()` to pry into the script
12
12
 
13
13
  import bpy
14
14
  import os
@@ -21,6 +21,7 @@ import math
21
21
  import mathutils
22
22
  import random
23
23
  import uuid
24
+ import sys
24
25
 
25
26
  exec(open("lib/glitch3d/bpy/helpers.py").read())
26
27
 
@@ -36,7 +37,7 @@ REFLECTOR_SCALE = 5
36
37
  REFLECTOR_STRENGTH = 12
37
38
  REFLECTOR_LOCATION_PADDING = 10
38
39
  PROPS_NUMBER = 100
39
- SHADERS = ['ShaderNodeBsdfGlossy', 'ShaderNodeBsdfDiffuse', 'ShaderNodeBsdfVelvet']
40
+ SHADERS = ['ShaderNodeBsdfGlossy', 'ShaderNodeBsdfDiffuse', 'ShaderNodeBsdfVelvet', 'ShaderNodeEmission']
40
41
 
41
42
  # Scene
42
43
  new_scene = bpy.data.scenes.new("Automated Render Scene")
@@ -56,13 +57,18 @@ context.scene.render.image_settings.file_format='PNG'
56
57
 
57
58
  if mode == 'high':
58
59
  context.scene.render.image_settings.compression = 90
59
- context.scene.cycles.samples = 500
60
+ context.scene.cycles.samples = 100
60
61
  context.scene.render.resolution_percentage = 100
61
62
 
63
+
64
+ # Delete current objects
65
+ for index, object in enumerate(bpy.data.objects):
66
+ bpy.data.objects.remove(object)
67
+
62
68
  # Load model
63
69
  model_path = os.path.join(file)
64
70
  bpy.ops.import_scene.obj(filepath = model_path, use_edges=True)
65
- model_object = bpy.data.objects['Glitch3D']
71
+ model_object = bpy.data.objects[0]
66
72
 
67
73
  # Use center of mass to center object
68
74
  model_object.select = True
@@ -76,37 +82,42 @@ camera_data = bpy.data.cameras.new('Render Camera')
76
82
  bpy.data.objects.new('Render Camera', object_data=camera_data)
77
83
  camera_object = bpy.data.objects['Render Camera']
78
84
  new_scene.objects.link(camera_object)
79
- camera_object.location = (8, 8, 0)
85
+ camera_object.location = (8, 8, 1)
86
+
87
+ empty_materials()
80
88
 
81
89
  # Add reflectors
82
90
  bpy.ops.mesh.primitive_plane_add(location=(0,8 + REFLECTOR_LOCATION_PADDING, 0))
83
91
  bpy.ops.mesh.primitive_plane_add(location=(8 + REFLECTOR_LOCATION_PADDING,0,0))
92
+ bpy.ops.mesh.primitive_plane_add(location=(0, 0, 8))
84
93
 
85
94
  plane1 = bpy.data.objects['Plane']
86
95
  plane2 = bpy.data.objects['Plane.001']
96
+ plane3 = bpy.data.objects['Plane.002']
87
97
 
88
98
  # Adjust camera
89
99
  context.scene.camera = camera_object
90
100
  look_at(camera_object, model_object)
91
- assign_material(model_object, create_cycles_material())
92
-
93
- for index, plane in enumerate([plane1, plane2]):
94
- plane.scale = (REFLECTOR_SCALE, REFLECTOR_SCALE, REFLECTOR_SCALE)
95
- plane.rotation_euler.x += math.radians(90)
96
- emissive_material = bpy.data.materials.new('Emissive Material #' + str(index))
97
- emissive_material.use_nodes = True
98
- emission_node = emissive_material.node_tree.nodes.new('ShaderNodeEmission')
99
- # Set color
100
- emission_node.inputs[0].default_value = rand_color_vector()
101
- # Set strength
102
- emission_node.inputs[1].default_value = REFLECTOR_STRENGTH
103
- assign_node_to_output(emissive_material, emission_node)
104
- assign_material(plane, emissive_material)
105
-
106
- # Tilt one of the reflectors
101
+ make_object_gold(model_object)
102
+
103
+ plane1.rotation_euler.x += math.radians(90)
104
+ plane2.rotation_euler.x += math.radians(90)
107
105
  plane2.rotation_euler.z += math.radians(90)
108
106
 
109
- # Add other elements
107
+ for plane in [plane1, plane2, plane3]:
108
+ make_object_reflector(plane)
109
+
110
+ # Make floor
111
+ bpy.ops.mesh.primitive_plane_add(location=(0,0,-2))
112
+ floor = bpy.data.objects['Plane.003']
113
+ floor.scale = (8,8,8)
114
+ floor_material = create_cycles_material()
115
+ assign_texture_to_material(floor_material, random_texture())
116
+ assign_material(floor, floor_material)
117
+
118
+ # Add props
119
+ props = []
120
+
110
121
  for index in range(0, int(PROPS_NUMBER)):
111
122
  bpy.ops.mesh.primitive_cube_add(location=rand_location(),radius=rand_scale(), rotation=rand_rotation())
112
123
  if index == 0:
@@ -118,35 +129,90 @@ for index in range(0, int(PROPS_NUMBER)):
118
129
  else:
119
130
  object_name = 'Cube.00' + str(index)
120
131
  object = bpy.data.objects[object_name]
132
+ props.append(object)
121
133
  new_material = create_cycles_material()
122
- assign_random_texture_to_material(new_material)
134
+ assign_texture_to_material(new_material, random_texture())
123
135
  assign_material(object, new_material)
124
136
 
125
137
  for index in range(0, int(PROPS_NUMBER)):
126
- bpy.ops.mesh.primitive_circle_add(location=rand_location(),radius=rand_scale(), rotation=rand_rotation())
138
+ bpy.ops.mesh.primitive_torus_add(location=rand_location(), rotation=rand_rotation(), major_radius=rand_scale(), minor_radius=rand_scale())
127
139
  if index == 0:
128
- object_name = 'Circle'
140
+ object_name = 'Torus'
129
141
  elif index > 9:
130
- object_name = 'Circle.0' + str(index)
142
+ object_name = 'Torus.0' + str(index)
131
143
  elif index > 99:
132
- object_name = 'Circle.' + str(index)
144
+ object_name = 'Torus.' + str(index)
133
145
  else:
134
- object_name = 'Circle.00' + str(index)
146
+ object_name = 'Torus.00' + str(index)
135
147
  object = bpy.data.objects[object_name]
148
+ props.append(object)
136
149
  new_material = create_cycles_material()
137
- assign_random_texture_to_material(new_material)
150
+ assign_texture_to_material(new_material, random_texture())
151
+ assign_material(object, new_material)
152
+
153
+ for index in range(0, int(PROPS_NUMBER)):
154
+ bpy.ops.mesh.primitive_cone_add(location=rand_location(), depth=1.0, rotation=rand_rotation(), radius1=rand_scale(), radius2=rand_scale())
155
+ if index == 0:
156
+ object_name = 'Cone'
157
+ elif index > 9:
158
+ object_name = 'Cone.0' + str(index)
159
+ elif index > 99:
160
+ object_name = 'Cone.' + str(index)
161
+ else:
162
+ object_name = 'Cone.00' + str(index)
163
+ object = bpy.data.objects[object_name]
164
+ props.append(object)
165
+ new_material = create_cycles_material()
166
+ assign_texture_to_material(new_material, random_texture())
167
+ assign_material(object, new_material)
168
+
169
+ # Import guns
170
+ for index in range(0, 5):
171
+ model_path_m4a1 = os.path.join('fixtures/m4a1.obj')
172
+ bpy.ops.import_scene.obj(filepath = model_path_m4a1, use_edges=True)
173
+ if index == 0:
174
+ object_name = 'm4a1'
175
+ elif index > 9:
176
+ object_name = 'm4a1.0' + str(index)
177
+ elif index > 99:
178
+ object_name = 'm4a1.' + str(index)
179
+ else:
180
+ object_name = 'm4a1.00' + str(index)
181
+ object = bpy.data.objects[object_name]
182
+ props.append(object)
183
+ object.location = rand_location()
184
+ object.scale = rand_scale_vector()
185
+ object.rotation_euler = rand_rotation()
186
+ new_material = create_cycles_material()
187
+ assign_texture_to_material(new_material, random_texture())
138
188
  assign_material(object, new_material)
139
189
 
140
190
  # Add background to world
141
191
  world = bpy.data.worlds[0]
142
192
  world.use_nodes = True
143
193
  world_node_tree = world.node_tree
144
- # code.interact(local=dict(globals(), **locals()))
145
194
  gradient_node = world_node_tree.nodes.new(type="ShaderNodeTexGradient")
195
+ texture_node = world_node_tree.nodes.new(type="ShaderNodeTexGradient")
196
+
197
+ output_node = world_node_tree.nodes['Background']
198
+ texture_node = world_node_tree.nodes.new('ShaderNodeTexture')
199
+ world_node_tree.links.new(texture_node.outputs[0], output_node.inputs[0])
200
+ texture_path = os.path.expanduser('fixtures/textures/25.jpg')
201
+ new_texture = bpy.data.textures.new('ColorTex', type = 'IMAGE')
202
+ new_texture.image = bpy.data.images.load(texture_path)
203
+ texture_node.texture = new_texture
204
+
146
205
  background_node = world_node_tree.nodes['Background']
147
206
  world_node_tree.links.new(gradient_node.outputs['Color'], background_node.inputs['Color'])
148
207
  gradient_node.gradient_type = 'EASING'
149
208
 
209
+ bpy.ops.object.mode_set(mode='EDIT')
210
+ # UV unwrap objects
211
+ for model in bpy.data.objects:
212
+ context.scene.objects.active = model
213
+ bpy.ops.uv.unwrap()
214
+ bpy.ops.object.mode_set(mode = 'OBJECT')
215
+
150
216
  # ------
151
217
  # Shoot
152
218
  # ------
@@ -154,6 +220,8 @@ print('Rendering images with resolution: ' + str(context.scene.render.resolution
154
220
  for index in range(0, int(shots_number)):
155
221
  print("-------------------------- " + str(index) + " --------------------------")
156
222
  rotate(model_object, index)
223
+ for prop in props:
224
+ prop.rotation_euler = rand_rotation()
157
225
  shoot(camera_object, model_object, output_name(index, model_path))
158
226
 
159
227
  print('FINISHED ¯\_(ツ)_/¯')
@@ -15,7 +15,7 @@ module Glitch3d
15
15
  end
16
16
 
17
17
  def selected_area(vertices_objects_array)
18
- Vertex.subset(x: :negative?, y: :positive?, z: :zero?, vertex_list: vertices_objects_array)
18
+ Vertex.subset(x: :positive?, y: :positive?, z: :positive?, vertex_list: vertices_objects_array)
19
19
  end
20
20
 
21
21
  def target(vertices_objects_array)
@@ -0,0 +1,11 @@
1
+ module Glitch3d
2
+ module None
3
+ def alter_vertices(vertices_objects_array)
4
+ vertices_objects_array
5
+ end
6
+
7
+ def alter_faces(faces_objects_array, _)
8
+ faces_objects_array
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module Glitch3d
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glitch3d
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - pskl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-04 00:00:00.000000000 Z
11
+ date: 2017-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -129,6 +129,7 @@ files:
129
129
  - lib/glitch3d/objects/vertex.rb
130
130
  - lib/glitch3d/strategies/default.rb
131
131
  - lib/glitch3d/strategies/localized.rb
132
+ - lib/glitch3d/strategies/none.rb
132
133
  - lib/glitch3d/version.rb
133
134
  homepage: http://pascal.cc
134
135
  licenses: