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.
- checksums.yaml +7 -0
- data/LICENSE +341 -0
- data/README.md +92 -0
- data/SETUP.md +70 -0
- data/data/assets/Texture/A011a.tga +0 -0
- data/data/assets/untitled.awp3d +0 -0
- data/data/cube.mtl +12 -0
- data/data/cube.obj +246 -0
- data/data/cube.raw +12 -0
- data/data/engine_conf.json +9 -0
- data/data/fighter.raw +19198 -0
- data/data/font/100.raw +78 -0
- data/data/font/101.raw +99 -0
- data/data/font/102.raw +58 -0
- data/data/font/103.raw +258 -0
- data/data/font/104.raw +55 -0
- data/data/font/105.raw +48 -0
- data/data/font/106.raw +72 -0
- data/data/font/107.raw +6 -0
- data/data/font/108.raw +2 -0
- data/data/font/109.raw +105 -0
- data/data/font/110.raw +55 -0
- data/data/font/111.raw +96 -0
- data/data/font/112.raw +78 -0
- data/data/font/113.raw +78 -0
- data/data/font/114.raw +53 -0
- data/data/font/115.raw +132 -0
- data/data/font/116.raw +56 -0
- data/data/font/117.raw +54 -0
- data/data/font/118.raw +5 -0
- data/data/font/119.raw +11 -0
- data/data/font/120.raw +10 -0
- data/data/font/121.raw +6 -0
- data/data/font/122.raw +6 -0
- data/data/font/33.raw +118 -0
- data/data/font/37.raw +194 -0
- data/data/font/38.raw +200 -0
- data/data/font/39.raw +4 -0
- data/data/font/40.raw +48 -0
- data/data/font/41.raw +48 -0
- data/data/font/42.raw +226 -0
- data/data/font/43.raw +10 -0
- data/data/font/45.raw +2 -0
- data/data/font/46.raw +46 -0
- data/data/font/47.raw +2 -0
- data/data/font/48.raw +96 -0
- data/data/font/49.raw +2 -0
- data/data/font/50.raw +87 -0
- data/data/font/51.raw +145 -0
- data/data/font/52.raw +15 -0
- data/data/font/53.raw +76 -0
- data/data/font/54.raw +121 -0
- data/data/font/55.raw +4 -0
- data/data/font/56.raw +194 -0
- data/data/font/57.raw +133 -0
- data/data/font/61.raw +4 -0
- data/data/font/63.raw +117 -0
- data/data/font/65.raw +11 -0
- data/data/font/66.raw +108 -0
- data/data/font/67.raw +96 -0
- data/data/font/68.raw +54 -0
- data/data/font/69.raw +10 -0
- data/data/font/70.raw +8 -0
- data/data/font/71.raw +100 -0
- data/data/font/72.raw +10 -0
- data/data/font/73.raw +2 -0
- data/data/font/74.raw +39 -0
- data/data/font/75.raw +9 -0
- data/data/font/76.raw +4 -0
- data/data/font/77.raw +13 -0
- data/data/font/78.raw +8 -0
- data/data/font/79.raw +96 -0
- data/data/font/80.raw +56 -0
- data/data/font/81.raw +124 -0
- data/data/font/82.raw +94 -0
- data/data/font/83.raw +120 -0
- data/data/font/84.raw +6 -0
- data/data/font/85.raw +76 -0
- data/data/font/86.raw +5 -0
- data/data/font/87.raw +11 -0
- data/data/font/88.raw +10 -0
- data/data/font/89.raw +7 -0
- data/data/font/90.raw +6 -0
- data/data/font/91.raw +6 -0
- data/data/font/93.raw +6 -0
- data/data/font/94.raw +5 -0
- data/data/font/95.raw +2 -0
- data/data/font/97.raw +174 -0
- data/data/font/98.raw +100 -0
- data/data/font/99.raw +96 -0
- data/data/ground.raw +12 -0
- data/data/man.mtl +12 -0
- data/data/man.obj +7547 -0
- data/data/robo.mtl +11 -0
- data/data/robo.obj +42065 -0
- data/data/space.json +49 -0
- data/data/sphere.raw +1216 -0
- data/data/texture/Charcoal-2.jpg +0 -0
- data/data/texture/man.png +0 -0
- data/data/texture/man.tif +0 -0
- data/data/texture/t.jpg +0 -0
- data/data/texture/wood.jpg +0 -0
- data/data/texture/wood.png +0 -0
- data/data/texture/x.jpg +0 -0
- data/data/untitled.raw +124 -0
- data/data/w.raw +12474 -0
- data/data/wings.raw +45670 -0
- data/lib/BlackBook/anim.rb +184 -0
- data/lib/BlackBook/b3dobject.rb +475 -0
- data/lib/BlackBook/base.rb +79 -0
- data/lib/BlackBook/camera.rb +202 -0
- data/lib/BlackBook/color.rb +29 -0
- data/lib/BlackBook/constants.rb +327 -0
- data/lib/BlackBook/engine.rb +172 -0
- data/lib/BlackBook/functions.rb +650 -0
- data/lib/BlackBook/light.rb +91 -0
- data/lib/BlackBook/logger.rb +86 -0
- data/lib/BlackBook/material.rb +98 -0
- data/lib/BlackBook/registry.rb +71 -0
- data/lib/BlackBook/space.rb +396 -0
- data/lib/BlackBook/stime.rb +64 -0
- data/lib/Plugins/string_color.rb +74 -0
- data/lib/blackbook/version.rb +5 -0
- data/lib/blackbook.rb +52 -0
- data/lib/plugins.rb +32 -0
- data/lib/ui/button.rb +115 -0
- data/lib/ui/edit.rb +105 -0
- data/lib/ui/text.rb +284 -0
- data/lib/ui/ui.rb +88 -0
- data/lib/ui/ui_element.rb +45 -0
- data/lib/ui/window.rb +138 -0
- data/lib/ui.rb +30 -0
- data/lib/zipfile.rb +27 -0
- 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
|