class Blender3d::Model
Attributes
blocks[R]
codes[R]
header[R]
pointers[R]
Public Class Methods
from_file(path)
click to toggle source
# File lib/blender-3d/model.rb, line 5 def self.from_file(path) File.open(path, 'rb') { |file| new(file) } end
new(file = nil)
click to toggle source
# File lib/blender-3d/model.rb, line 9 def initialize(file = nil) @blocks = [] deserialize(file) if file end
Public Instance Methods
create_reader(file)
click to toggle source
# File lib/blender-3d/model.rb, line 48 def create_reader(file) ObjectReader.new(file, self) end
deserialize(file)
click to toggle source
# File lib/blender-3d/model.rb, line 14 def deserialize(file) @header = FileHeader.new(file) reader = create_reader(file) @blocks.clear loop do @blocks << FileBlock.new(reader) break if reader.tell == reader.file.size end @pointers = @blocks.reject { |block| block.code == 'ENDB' }.map { |block| [block.pointer, block] }.to_h dna_block = self.dna_block return self unless dna_block render_block = @blocks.find { |b| b.code == 'REND' } if render_block render_block.type_index = dna_block.data.structures.size dna_block.data.structures << render_info end @blocks.select { |block| block.type_index != 0 }.each do |block| block.type = dna_block.data.structures[block.type_index] end @blocks.select(&:type).each_with_index do |block, i| block.parse_data(self) end @codes = @blocks.group_by(&:code).sort.to_h self end
dna_block()
click to toggle source
# File lib/blender-3d/model.rb, line 52 def dna_block @blocks.find { |block| block.code == 'DNA1' } end
render_info()
click to toggle source
# File lib/blender-3d/model.rb, line 56 def render_info @render_info ||= begin sizeof_int = dna_block.data.types.find { |name, _| name == 'int' }.last struct_size = 2 * sizeof_int + 64 StructureDefinition.new('RenderInfo', struct_size, [ Field.new(SimpleType.new('int'), 'sfra'), Field.new(SimpleType.new('int'), 'efra'), Field.new(FixedLengthStringType.new(64), 'scene_name'), ]) end end
to_xml()
click to toggle source
# File lib/blender-3d/model.rb, line 68 def to_xml content = blocks.reject { |b| b.code == 'DNA1' }.map(&:to_xml) REXML::Element.new(self.class.basename).tap do |e| e.add_attribute 'identifier', @header.identifier e.add_attribute 'pointer_size', @header.pointer_size.to_s e.add_attribute 'endianness', @header.endianness.to_s e.add_attribute 'version', @header.version content.each_with_index do |c, i| c.add_attribute 'index', i.to_s e << c end end end