blackbook3d 0.5.0

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.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +341 -0
  3. data/README.md +92 -0
  4. data/SETUP.md +70 -0
  5. data/data/assets/Texture/A011a.tga +0 -0
  6. data/data/assets/untitled.awp3d +0 -0
  7. data/data/cube.mtl +12 -0
  8. data/data/cube.obj +246 -0
  9. data/data/cube.raw +12 -0
  10. data/data/engine_conf.json +9 -0
  11. data/data/fighter.raw +19198 -0
  12. data/data/font/100.raw +78 -0
  13. data/data/font/101.raw +99 -0
  14. data/data/font/102.raw +58 -0
  15. data/data/font/103.raw +258 -0
  16. data/data/font/104.raw +55 -0
  17. data/data/font/105.raw +48 -0
  18. data/data/font/106.raw +72 -0
  19. data/data/font/107.raw +6 -0
  20. data/data/font/108.raw +2 -0
  21. data/data/font/109.raw +105 -0
  22. data/data/font/110.raw +55 -0
  23. data/data/font/111.raw +96 -0
  24. data/data/font/112.raw +78 -0
  25. data/data/font/113.raw +78 -0
  26. data/data/font/114.raw +53 -0
  27. data/data/font/115.raw +132 -0
  28. data/data/font/116.raw +56 -0
  29. data/data/font/117.raw +54 -0
  30. data/data/font/118.raw +5 -0
  31. data/data/font/119.raw +11 -0
  32. data/data/font/120.raw +10 -0
  33. data/data/font/121.raw +6 -0
  34. data/data/font/122.raw +6 -0
  35. data/data/font/33.raw +118 -0
  36. data/data/font/37.raw +194 -0
  37. data/data/font/38.raw +200 -0
  38. data/data/font/39.raw +4 -0
  39. data/data/font/40.raw +48 -0
  40. data/data/font/41.raw +48 -0
  41. data/data/font/42.raw +226 -0
  42. data/data/font/43.raw +10 -0
  43. data/data/font/45.raw +2 -0
  44. data/data/font/46.raw +46 -0
  45. data/data/font/47.raw +2 -0
  46. data/data/font/48.raw +96 -0
  47. data/data/font/49.raw +2 -0
  48. data/data/font/50.raw +87 -0
  49. data/data/font/51.raw +145 -0
  50. data/data/font/52.raw +15 -0
  51. data/data/font/53.raw +76 -0
  52. data/data/font/54.raw +121 -0
  53. data/data/font/55.raw +4 -0
  54. data/data/font/56.raw +194 -0
  55. data/data/font/57.raw +133 -0
  56. data/data/font/61.raw +4 -0
  57. data/data/font/63.raw +117 -0
  58. data/data/font/65.raw +11 -0
  59. data/data/font/66.raw +108 -0
  60. data/data/font/67.raw +96 -0
  61. data/data/font/68.raw +54 -0
  62. data/data/font/69.raw +10 -0
  63. data/data/font/70.raw +8 -0
  64. data/data/font/71.raw +100 -0
  65. data/data/font/72.raw +10 -0
  66. data/data/font/73.raw +2 -0
  67. data/data/font/74.raw +39 -0
  68. data/data/font/75.raw +9 -0
  69. data/data/font/76.raw +4 -0
  70. data/data/font/77.raw +13 -0
  71. data/data/font/78.raw +8 -0
  72. data/data/font/79.raw +96 -0
  73. data/data/font/80.raw +56 -0
  74. data/data/font/81.raw +124 -0
  75. data/data/font/82.raw +94 -0
  76. data/data/font/83.raw +120 -0
  77. data/data/font/84.raw +6 -0
  78. data/data/font/85.raw +76 -0
  79. data/data/font/86.raw +5 -0
  80. data/data/font/87.raw +11 -0
  81. data/data/font/88.raw +10 -0
  82. data/data/font/89.raw +7 -0
  83. data/data/font/90.raw +6 -0
  84. data/data/font/91.raw +6 -0
  85. data/data/font/93.raw +6 -0
  86. data/data/font/94.raw +5 -0
  87. data/data/font/95.raw +2 -0
  88. data/data/font/97.raw +174 -0
  89. data/data/font/98.raw +100 -0
  90. data/data/font/99.raw +96 -0
  91. data/data/ground.raw +12 -0
  92. data/data/man.mtl +12 -0
  93. data/data/man.obj +7547 -0
  94. data/data/robo.mtl +11 -0
  95. data/data/robo.obj +42065 -0
  96. data/data/space.json +49 -0
  97. data/data/sphere.raw +1216 -0
  98. data/data/texture/Charcoal-2.jpg +0 -0
  99. data/data/texture/man.png +0 -0
  100. data/data/texture/man.tif +0 -0
  101. data/data/texture/t.jpg +0 -0
  102. data/data/texture/wood.jpg +0 -0
  103. data/data/texture/wood.png +0 -0
  104. data/data/texture/x.jpg +0 -0
  105. data/data/untitled.raw +124 -0
  106. data/data/w.raw +12474 -0
  107. data/data/wings.raw +45670 -0
  108. data/lib/BlackBook/anim.rb +184 -0
  109. data/lib/BlackBook/b3dobject.rb +475 -0
  110. data/lib/BlackBook/base.rb +79 -0
  111. data/lib/BlackBook/camera.rb +202 -0
  112. data/lib/BlackBook/color.rb +29 -0
  113. data/lib/BlackBook/constants.rb +327 -0
  114. data/lib/BlackBook/engine.rb +172 -0
  115. data/lib/BlackBook/functions.rb +650 -0
  116. data/lib/BlackBook/light.rb +91 -0
  117. data/lib/BlackBook/logger.rb +86 -0
  118. data/lib/BlackBook/material.rb +98 -0
  119. data/lib/BlackBook/registry.rb +71 -0
  120. data/lib/BlackBook/space.rb +396 -0
  121. data/lib/BlackBook/stime.rb +64 -0
  122. data/lib/Plugins/string_color.rb +74 -0
  123. data/lib/blackbook/version.rb +5 -0
  124. data/lib/blackbook.rb +52 -0
  125. data/lib/plugins.rb +32 -0
  126. data/lib/ui/button.rb +115 -0
  127. data/lib/ui/edit.rb +105 -0
  128. data/lib/ui/text.rb +284 -0
  129. data/lib/ui/ui.rb +88 -0
  130. data/lib/ui/ui_element.rb +45 -0
  131. data/lib/ui/window.rb +138 -0
  132. data/lib/ui.rb +30 -0
  133. data/lib/zipfile.rb +27 -0
  134. metadata +254 -0
@@ -0,0 +1,184 @@
1
+ ##############################################################################
2
+ # BlackBook 3D Engine
3
+ # Copyright (C) 2015, 2021 Sinan ISLEKDEMIR / DarkSpy
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program; if not, write to the Free Software Foundation, Inc.,
17
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ ##############################################################################
19
+
20
+ ################################################################
21
+ # Project BlackBook
22
+ # Lead Engineer: Sinan ISLEKDEMIR
23
+ # anim.rb: DarkSpy
24
+ # Simulation Engine Ruby Sources
25
+ ################################################################
26
+
27
+ require 'opengl'
28
+ require 'BlackBook/base'
29
+ require 'BlackBook/constants'
30
+ require 'BlackBook/stime'
31
+ require 'BlackBook/b3dobject'
32
+ require 'pp'
33
+ require 'zipfile'
34
+
35
+
36
+ module BlackBook
37
+ class Anim < B3DObject
38
+ attr_accessor :num_frames, :_loop, :_time, :fps, :_frame, :_path
39
+ attr_accessor :_from_frame, :_to_frame, :_active_framecount, :_frame_period, :animate, :animations, :frames
40
+ attr_accessor :texture_name
41
+
42
+ def initialize(fps=30)
43
+ @frames = []
44
+ @_frame = 0
45
+ @num_frames = 0
46
+ @_time = 0
47
+ @_path = ""
48
+ @_loop = false
49
+ @_from_frame = 0
50
+ @_to_frame = 0
51
+ @_active_framecount = 0
52
+ @fps = fps
53
+ @_frame_period = 1.0 / fps
54
+ @animate = true
55
+ @animations = {} #: Dict[str, Tuple[int, int]] = {}
56
+ @objects = []
57
+ @texture_name=''
58
+ end
59
+
60
+ def start()
61
+ @animate = true
62
+ end
63
+ def pause()
64
+ @animate = false
65
+ end
66
+ def stop()
67
+ @animate = false
68
+ @_time = 0.0
69
+ end
70
+
71
+ def set_range(from_frame, to_frame)
72
+ if from_frame >= @num_frames
73
+ return "Frame range error - from_frame out of bounds"
74
+ end
75
+ if to_frame >= @num_frames
76
+ return "Frame range error - to_frame out of bounds"
77
+ end
78
+ if from_frame < 0 or to_frame < 0
79
+ return "Frame range error - Negative value defined"
80
+ end
81
+ @_from_frame = from_frame
82
+ @_to_frame = to_frame
83
+ @_active_framecount = to_frame - from_frame
84
+ @_frame_period = 1.0 / @fps
85
+ end
86
+
87
+ def set_animation(name, from_frame, to_frame)
88
+ @animations[name] = [from_frame, to_frame]
89
+ end
90
+
91
+ def run_animation(name)
92
+ if not @animations.has_key?(name)
93
+ return "Animation not defined"
94
+ end
95
+ self.set_range(@animations[name][0], @animations[name][1])
96
+ end
97
+
98
+ def load_texture(texture) #added
99
+ @texture_name = texture # for lazy load. just save it
100
+ end
101
+
102
+ def load_file(filename)
103
+ if not FileTest::exist?(filename)
104
+ return "File not found: {filename}"
105
+ end
106
+ @_path = File.dirname(filename)
107
+ archive = ZipFile.new(filename)
108
+ files = archive.namelist()
109
+
110
+ a=0
111
+ n=[]
112
+ loop {
113
+ f = files[a]; a += 1; n<<f.to_s.split('.')[0].to_i;
114
+ break if a>=files.length
115
+ }
116
+ max_frame, min_frame = n.max, n.min
117
+ f = min_frame
118
+ ret, dname = dir_make(folder_gen())
119
+ puts "dirmake #{ret}, #{dname}"
120
+ if ret == 0
121
+ return "temp folder makes fail"
122
+ else
123
+ $FOLDER << dname
124
+ end
125
+ while f < max_frame
126
+ #progress(f, max_frame - 1)
127
+ #wobj = B3DObject.new()
128
+ #wobj.path = @_path
129
+ #data = archive.read("#{f.to_s}.obj")
130
+ #material = archive.read("#{f.to_s}.mtl")
131
+
132
+ #wobj.material.load_texture(material)
133
+ #wobj.load_obj_from_mem(data)
134
+ objs = archive.write(dname, "#{f.to_s}.obj")
135
+ archive.write(dname, "#{f.to_s}.mtl")
136
+ #puts "objs #{objs}"
137
+ @frames << objs
138
+ f += 1
139
+ end
140
+ @_active_framecount = max_frame - min_frame
141
+ @num_frames = max_frame - min_frame
142
+ #archive.close()
143
+ end
144
+ end
145
+ =begin
146
+ def render(self, lit: bool, shader: Shader, parent_matrix: Optional[np.ndarray] = None, _primitive: int = None):
147
+ if not self._visible:
148
+ return
149
+ self.update_matrix(parent_matrix=parent_matrix)
150
+ self.track()
151
+
152
+ if not self.animate:
153
+ self.frames[0].render(lit, shader, self._model_matrix)
154
+ return
155
+
156
+ if self._time == 0:
157
+ self._time = time.time()
158
+
159
+ if time.time() - self._time >= self._frame_period:
160
+ self._frame = (self._frame + 1) % self._active_framecount
161
+ self._time = time.time()
162
+ render_frame = self._frame + self._from_frame
163
+ self.frames[render_frame].render(lit, shader, self._model_matrix)
164
+ end
165
+
166
+ def toggle_wireframe(self) -> None:
167
+ d = (self.material.display + 1) % 3
168
+
169
+ for mat in self.materials.values():
170
+ mat.display = d
171
+ mat.particle_size = 0.01
172
+
173
+ if d == POINTS:
174
+ self.shader = PARTICLE_SHADER
175
+ self.refresh()
176
+ else:
177
+ self.shader = DEFAULT_SHADER
178
+ self.refresh()
179
+
180
+ for frame in self.frames:
181
+ frame.toggle_wireframe()
182
+ end
183
+ =end
184
+ end
@@ -0,0 +1,475 @@
1
+ ##############################################################################
2
+ # BlackBook 3D Engine
3
+ # Copyright (C) 2015 Sinan ISLEKDEMIR
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program; if not, write to the Free Software Foundation, Inc.,
17
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+ ##############################################################################
19
+
20
+ ################################################################
21
+ # Project BlackBook
22
+ # Lead Engineer: Sinan ISLEKDEMIR
23
+ # Simulation Engine Ruby Sources
24
+ ################################################################
25
+
26
+ require 'opengl'
27
+ require 'BlackBook/base'
28
+ require 'BlackBook/constants'
29
+ require 'BlackBook/stime'
30
+ require 'pp'
31
+
32
+ module BlackBook
33
+ #
34
+ # 3D Object - Base Class
35
+ #
36
+ # @author [sinan islekdemir]
37
+ #
38
+ # @attr faces [Array] holds the array of faces inside the object
39
+ # @attr mass [Float] total mass of the object
40
+ # @attr roll [Float] Roll angle in degrees
41
+ # @attr pitch [Float] Pitch angle in degrees
42
+ # @attr yaw [Float] Yaw angle in degrees
43
+ # @attr position [CVector] Position vector of the object
44
+ # @attr time [Float] Time frame of the object
45
+ # @attr name [String] Name of the object
46
+ # @attr scale [CVector] Scale of the object for rendering
47
+ # @attr index [Integer] GlGenList OpenGL List Index
48
+ # @attr min [CVector] Minimum coordinates
49
+ # @attr max [CVector] Maximum coordinates
50
+ #
51
+ class B3DObject < Base
52
+ attr_accessor :faces, :roll, :pitch, :yaw, :time, :name, :scale, :index,
53
+ :min, :max, :data_size, :normal_index, :elasticity,
54
+ :type, :material, :matrix, :radius
55
+ PARTICLE = 0
56
+ SOLID_CUBE = 1
57
+ SOLID_SPHERE = 2
58
+ SOLID_MESH = 3
59
+ SOFT_CUBE = 4
60
+ SOFT_SPHERE = 5
61
+ SOFT_MESH = 6
62
+
63
+ #
64
+ # Initialize basic variables with default.
65
+ #
66
+ # @return [BB3DObject] return self
67
+ def initialize
68
+ @vertices = []
69
+ @indices = []
70
+ @texcoords = []
71
+ @mass = 0.0
72
+ @roll = 0.0
73
+ @pitch = 0.0
74
+ @yaw = 0.0
75
+ @position = CVector.new(0, 0, 0, 1)
76
+ @scale = CVector.new(1, 1, 1, 1)
77
+ @min = nil
78
+ @max = nil
79
+ @index = -1
80
+ @time = STime.new
81
+ @vertex_data = []
82
+ @data_size = 0
83
+ @type = PARTICLE
84
+ @matrix = CMatrix.new
85
+ @radius = 0.0
86
+ @min = CVector.new(9999999, 9999999, 9999999)
87
+ @max = CVector.new(-9999999, -9999999, -9999999)
88
+ @material = Material.new
89
+ end
90
+
91
+ # Convert local vector to absolute coordinates
92
+ # @param [CVector] Vector
93
+ # @param [CMatrix] Absolute Matrix
94
+ # @return [CVector] Absolute Vector
95
+ def local_to_absolute(v)
96
+ v = BlackBook.vector_transform(v, @matrix.to_f)
97
+ v
98
+ end
99
+
100
+ # rotate object
101
+ # @param [Float] x axis
102
+ # @param [Float] y axis
103
+ # @param [Float] z axis
104
+ def rotate(x, y, z)
105
+ @matrix.rotate x, y, z
106
+ end
107
+
108
+ #
109
+ # Load position data
110
+ # @param data [Hash] Load Data hash. (Recursive scene loading from json)
111
+ #
112
+ # @return [CVector] Position vector
113
+ def load_position(data)
114
+ @matrix.pos.x = data['position'][0] if data.key?('position')
115
+ @matrix.pos.y = data['position'][1] if data.key?('position')
116
+ @matrix.pos.z = data['position'][2] if data.key?('position')
117
+ end
118
+
119
+ #
120
+ # Load Rotation Data
121
+ # @param data [Hash] Load Data hash. (Recursive scene loading from json)
122
+ #
123
+ # @return [Float] Returns Yaw Flaot
124
+ def load_rotation(data)
125
+ @roll = data['roll'] if data.key?('roll')
126
+ @pitch = data['pitch'] if data.key?('pitch')
127
+ @yaw = data['yaw'] if data.key?('yaw')
128
+ end
129
+
130
+ #
131
+ # Load Time Data
132
+ # @param data [Hash] Load Data hash. (Recursive scene loading from json)
133
+ #
134
+ # @return [Float] Returns Time
135
+ def load_time(data)
136
+ @time = data['time'] if data.key?('time')
137
+ end
138
+
139
+ def load_type(data)
140
+ @type = data['type'] if data.key?('type')
141
+ end
142
+
143
+ #
144
+ # Create a cube object.
145
+ # This is simply a raw cube loader.
146
+ # An alias to load_raw ...
147
+ #
148
+ # @return [Boolean] Load cube object
149
+ def create_cube
150
+ data_path = BlackBook::Registry.instance.read('data_path')
151
+ data_path = 'data' if data_path.nil?
152
+ load_raw data_path + '/cube.raw'
153
+ end
154
+
155
+ #
156
+ # Create a sphere object.
157
+ # This is simply a raw sphere loader.
158
+ # An alias to load_raw ...
159
+ #
160
+ # @return [Boolean] Load sphere object.
161
+ def create_sphere
162
+ data_path = BlackBook::Registry.instance.read('data_path')
163
+ data_path = 'data' if data_path.nil?
164
+ load_raw data_path + '/sphere.raw'
165
+ end
166
+
167
+ #
168
+ # Add a face to the boejct
169
+ # @param vertex_array [Array] Array of face data. (Creates a QUAD)
170
+ #
171
+ # @return [Boolean]
172
+ def add_face(v_array)
173
+ index = @vertices.count
174
+ v_1 = CVector.new(v_array[0], v_array[1], v_array[2])
175
+ v_2 = CVector.new(v_array[3], v_array[4], v_array[5])
176
+ v_3 = CVector.new(v_array[6], v_array[7], v_array[8])
177
+ @vertices << v_1
178
+ @vertices << v_2
179
+ @vertices << v_3
180
+ indice = CIndice.new
181
+ indice.vertice_index << index
182
+ indice.vertice_index << index + 1
183
+ indice.vertice_index << index + 2
184
+ indice.vertice_index << index
185
+ @indices << indice
186
+ end
187
+
188
+ #
189
+ # Load incoming array data into object.
190
+ # This function is used inside recursive json scene loader.
191
+ # @param data [Hash] Load Data hash. (Recursive scene loading from json)
192
+ #
193
+ # @return [Boolean] Last operation is load_time and returns its result
194
+ def load(data)
195
+ load_position data
196
+ load_rotation data
197
+ load_time data
198
+ load_type data
199
+ case @type
200
+ when 1
201
+ create_cube
202
+ when 2
203
+ create_sphere
204
+ when 3
205
+ load_raw data['filename']
206
+ end
207
+ @scale.from_array(data['scale']) if data.key?('scale')
208
+ end
209
+
210
+ #
211
+ # Update min and max vectors
212
+ # @param v [CVector] CVector added to object
213
+ #
214
+ # @return [CVector] Max Vector
215
+ def update_min_max(v)
216
+ @min.x = v.x if v.x < @min.x
217
+ @min.y = v.y if v.y < @min.y
218
+ @min.z = v.z if v.z < @min.z
219
+ @max.x = v.x if v.x > @max.x
220
+ @max.y = v.y if v.y > @max.y
221
+ @max.z = v.z if v.z > @max.z
222
+ @radius = @min.distance(@max) / 2.0
223
+ end
224
+ #
225
+ # Build OpenGL List from faces
226
+ #
227
+ # @return [Float] Bounding radius of the object
228
+ def build_list
229
+ n = Time.now.to_f
230
+ shader = BlackBook::Registry.instance.read('shader')
231
+ shader = 'displaylist' if shader.nil?
232
+ v1 = CVector.new(0, 0, 0, 1)
233
+ v2 = v1.clone
234
+ v3 = v1.clone
235
+ x = @vertices.map { |v| v.x }.minmax
236
+ y = @vertices.map { |v| v.y }.minmax
237
+ z = @vertices.map { |v| v.z }.minmax
238
+ @min.x = x[0]
239
+ @max.x = x[1]
240
+ @min.y = y[0]
241
+ @max.y = y[1]
242
+ @min.z = z[0]
243
+ @max.z = z[1]
244
+
245
+ case shader
246
+ when 'displaylist'
247
+ @index = GL.GenLists(1)
248
+ GL.NewList(@index, GL::COMPILE)
249
+ GL.LineWidth(2)
250
+ @indices.each do |indice|
251
+ v1 = @vertices[indice.vertice_index[0]]
252
+ v2 = @vertices[indice.vertice_index[1]]
253
+ v3 = @vertices[indice.vertice_index[2]]
254
+ normal = BlackBook.calc_plane_normal(v1, v2, v3)
255
+ GL.Begin(GL::TRIANGLES)
256
+ 0.upto(indice.vertice_index.count - 1) do |i|
257
+ t = indice.texcoord_index.count > 0
258
+ vertex = @vertices[indice.vertice_index[i]]
259
+ texcrd = @texcoords[indice.texcoord_index[i]] if t
260
+
261
+ GL.Normal3f(normal.x, normal.y, normal.z)
262
+ GL.TexCoord2f(texcrd.x, texcrd.y) if t
263
+ GL.Vertex3f(vertex.x, vertex.y, vertex.z)
264
+ end
265
+ GL.End
266
+ end
267
+ GL.EndList
268
+ when 'vbo'
269
+ @index = GL.GenBuffers(3)
270
+ data = []
271
+ normals = []
272
+ textures = []
273
+ @indices.each do |indice|
274
+ v1 = @vertices[indice.vertice_index[0]]
275
+ v2 = @vertices[indice.vertice_index[1]]
276
+ v3 = @vertices[indice.vertice_index[2]]
277
+ normal = BlackBook.calc_plane_normal(v1, v2, v3)
278
+ 0.upto(indice.vertice_index.count - 1) do |i|
279
+ @t = indice.texcoord_index.count > 0
280
+ vertex = @vertices[indice.vertice_index[i]]
281
+ texcrd = @texcoords[indice.texcoord_index[i]] if @t
282
+ data << vertex.x
283
+ data << vertex.y
284
+ data << vertex.z
285
+ normals << normal.x
286
+ normals << normal.y
287
+ normals << normal.z
288
+ textures << texcrd.x if @t
289
+ textures << texcrd.y if @t
290
+ end
291
+ update_min_max(v1)
292
+ update_min_max(v2)
293
+ update_min_max(v3)
294
+ end
295
+ @data_size = data.length
296
+ GL.BindBuffer(GL::GL_ARRAY_BUFFER, @index[0])
297
+ GL.BufferData(
298
+ GL::GL_ARRAY_BUFFER,
299
+ data.length * 4,
300
+ data.pack('f*'),
301
+ GL::GL_STATIC_DRAW)
302
+ GL.BindBuffer(GL::GL_ARRAY_BUFFER, @index[1])
303
+ GL.BufferData(
304
+ GL::GL_ARRAY_BUFFER,
305
+ normals.length * 4,
306
+ normals.pack('f*'),
307
+ GL::GL_STATIC_DRAW
308
+ )
309
+ GL.BindBuffer(GL::GL_ARRAY_BUFFER, @index[2])
310
+ GL.BufferData(
311
+ GL::GL_ARRAY_BUFFER,
312
+ textures.length * 4,
313
+ textures.pack('f*'),
314
+ GL::GL_STATIC_DRAW)
315
+ data.clear
316
+ normals.clear
317
+ textures.clear
318
+ @indices.clear
319
+ @texcoords.clear
320
+ @vertices.clear
321
+ end
322
+ d = Time.now.to_f - n
323
+ puts "Build: #{d}\n"
324
+
325
+ end
326
+
327
+ #
328
+ # General rendering method.
329
+ #
330
+ # @return [Boolean] GL.PopMatrix is the last method called inside.
331
+ def render
332
+ build_list if @index == -1
333
+ # GL.Disable(GL::LIGHTING)
334
+ @material.start_render
335
+
336
+ GL.PushMatrix
337
+ GL.MultMatrixf(@matrix.to_array)
338
+
339
+ shader = BlackBook::Registry.instance.read('shader')
340
+ shader = 'displaylist' if shader.nil?
341
+ case shader
342
+ when 'displaylist'
343
+ GL.CallList(@index)
344
+ when 'vbo'
345
+ GL.EnableClientState(GL::GL_VERTEX_ARRAY)
346
+ GL.EnableClientState(GL::GL_NORMAL_ARRAY)
347
+ GL.EnableClientState(GL::GL_TEXTURE_COORD_ARRAY)
348
+ GL.BindBuffer(GL::GL_ARRAY_BUFFER, @index[0])
349
+ GL.VertexPointer(3, GL::GL_FLOAT, 0, 0)
350
+ GL.BindBuffer(GL::GL_ARRAY_BUFFER, @index[1])
351
+ GL.NormalPointer(GL::GL_FLOAT, 0, 0)
352
+ GL.BindBuffer(GL::GL_ARRAY_BUFFER, @index[2])
353
+ GL.TexCoordPointer(2, GL::GL_FLOAT, 0, 0)
354
+ GL.DrawArrays(GL::GL_QUADS, 0, @data_size / 3)
355
+ # GL.DrawElements(GL::TRIANGLES, @data_size / 3, GL::UNSIGNED_SHORT, 0)
356
+ GL.DisableClientState(GL::GL_VERTEX_ARRAY)
357
+ GL.DisableClientState(GL::GL_NORMAL_ARRAY)
358
+ GL.DisableClientState(GL::GL_TEXTURE_COORD_ARRAY)
359
+ GL.Flush
360
+ end
361
+
362
+ GL.PopMatrix
363
+ @material.end_render
364
+ # GL.Enable(GL::LIGHTING)
365
+ end
366
+
367
+ #
368
+ # Load Raw data object.
369
+ # This is the RAW File Type of Blender software (http://www.blender.org/)
370
+ # @param filename [String] File to be loaded.
371
+ #
372
+ # @return [Boolean] Return true on success
373
+ def load_raw(filename)
374
+ buffer = File.read filename
375
+ buffer.split("\n").each do |line|
376
+ f_items = line.split(' ').map { |x| x.to_f }
377
+ add_face f_items
378
+ end
379
+ calculate_radius
380
+ true
381
+ end
382
+
383
+ #
384
+ # Load Text based Wavefront Object
385
+ # This is the obj file type of Blender software (http://www.blender.org/)
386
+ # @param [String] filename
387
+ #
388
+ # @return [Boolean] Return true on success
389
+ def load_obj(filename)
390
+ @vertices = []
391
+ @texcoords = []
392
+ @indices = []
393
+ buffer = File.read filename
394
+ buffer = buffer.split("\n")
395
+ buffer.each do |line|
396
+ items = line.split(' ')
397
+ case items[0]
398
+ when 'v'
399
+ @vertices << CVector.new(items[1].to_f, items[2].to_f, items[3].to_f)
400
+ when 'vt'
401
+ @texcoords << CVector.new(items[1].to_f, items[2].to_f, 0)
402
+ when 'f'
403
+ indice = CIndice.new
404
+ items.each do |item|
405
+ next if item == 'f'
406
+ p = item.split '/'
407
+ indice.vertice_index << p[0].to_i - 1
408
+ indice.texcoord_index << p[1].to_i - 1 unless p[1].nil?
409
+ end
410
+ @indices << indice
411
+ end
412
+ end
413
+ calculate_radius
414
+ end
415
+
416
+ #
417
+ # Load Text based Wavefront Object
418
+ # This is the obj file type of Blender software (http://www.blender.org/)
419
+ # @param [String] buffer
420
+ #
421
+ # @return [Boolean] Return true on success
422
+ def load_obj_from_mem(buffer)
423
+ @vertices = []
424
+ @texcoords = []
425
+ @indices = []
426
+ #buffer = File.read filename
427
+ buffer = buffer.split("\n")
428
+ buffer.each do |line|
429
+ items = line.split(' ')
430
+ case items[0]
431
+ when 'v'
432
+ @vertices << CVector.new(items[1].to_f, items[2].to_f, items[3].to_f)
433
+ when 'vt'
434
+ @texcoords << CVector.new(items[1].to_f, items[2].to_f, 0)
435
+ when 'f'
436
+ indice = CIndice.new
437
+ items.each do |item|
438
+ next if item == 'f'
439
+ p = item.split '/'
440
+ indice.vertice_index << p[0].to_i - 1
441
+ indice.texcoord_index << p[1].to_i - 1 unless p[1].nil?
442
+ end
443
+ @indices << indice
444
+ end
445
+ end
446
+ calculate_radius
447
+ end
448
+
449
+ #
450
+ # Calculate bounding sphere radius from vertices
451
+ # Finds the maximum distance from origin to any vertex
452
+ #
453
+ # @return [Float] Calculated radius
454
+ def calculate_radius
455
+ return 0.0 if @vertices.empty?
456
+
457
+ # Calculate center of mass (centroid)
458
+ center_x = @vertices.map(&:x).sum / @vertices.size
459
+ center_y = @vertices.map(&:y).sum / @vertices.size
460
+ center_z = @vertices.map(&:z).sum / @vertices.size
461
+
462
+ # Find maximum distance from center
463
+ @radius = @vertices.map do |v|
464
+ dx = v.x - center_x
465
+ dy = v.y - center_y
466
+ dz = v.z - center_z
467
+ Math.sqrt(dx * dx + dy * dy + dz * dz)
468
+ end.max
469
+
470
+ @radius
471
+ end
472
+
473
+
474
+ end
475
+ end