Class: Bayonetta::WMBFile::Batch

Inherits:
LibBin::Structure
  • Object
show all
Defined in:
lib/bayonetta/wmb.rb

Instance Method Summary collapse

Constructor Details

#initializeBatch

Returns a new instance of Batch.



846
847
848
849
850
851
# File 'lib/bayonetta/wmb.rb', line 846

def initialize
  @header = BatchHeader::new
  @num_bone_ref = 0
  @bone_refs = []
  @indices = []
end

Instance Method Details

#add_ancestors_bone_refs(vertexes, bones) ⇒ Object



938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
# File 'lib/bayonetta/wmb.rb', line 938

def add_ancestors_bone_refs(vertexes, bones)
  if header.has_bone_refs != 0
    bone_refs_map = @bone_refs.each_with_index.collect { |b, i| [i, b] }.to_h
    used_bone_refs_indexes = vertex_indices.collect { |vi| vertexes[vi].bone_infos.get_indexes }.flatten.uniq
    new_bone_refs_list = used_bone_refs_indexes.collect{ |i| bone_refs_map[i] }.uniq.sort
    new_bone_refs_set = Set::new(new_bone_refs_list)
    new_bone_refs_list.each { |bi|
      new_bone_refs_set.merge(bones[bi].parents.collect(&:index))
    }
    new_bone_refs_list = new_bone_refs_set.to_a.sort
    new_bone_refs_reverse_map = new_bone_refs_list.each_with_index.collect { |b, i| [b, i] }.to_h
    translation_map = used_bone_refs_indexes.collect { |ri|
      [ri, new_bone_refs_reverse_map[bone_refs_map[ri]]]
    }.to_h
    vertex_indices.uniq.sort.each { |vi| vertexes[vi].bone_infos.remap_indexes(translation_map) }
    @bone_refs = new_bone_refs_list
    @num_bone_ref = @bone_refs.length
  end
end

#add_previous_bone_refs(vertexes, bones) ⇒ Object



958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
# File 'lib/bayonetta/wmb.rb', line 958

def add_previous_bone_refs(vertexes, bones)
  if header.has_bone_refs != 0
    bone_refs_map = @bone_refs.each_with_index.collect { |b, i| [i, b] }.to_h
    used_bone_refs_indexes = vertex_indices.collect { |vi| vertexes[vi].bone_infos.get_indexes }.flatten.uniq
    last_bone = used_bone_refs_indexes.collect{ |i| bone_refs_map[i] }.uniq.max
    new_bone_refs_list = (0..last_bone).to_a
    new_bone_refs_reverse_map = new_bone_refs_list.each_with_index.collect { |b, i| [b, i] }.to_h
    translation_map = used_bone_refs_indexes.collect { |ri|
      [ri, new_bone_refs_reverse_map[bone_refs_map[ri]]]
    }.to_h
    vertex_indices.uniq.sort.each { |vi| vertexes[vi].bone_infos.remap_indexes(translation_map) }
    @bone_refs = new_bone_refs_list
    @num_bone_ref = @bone_refs.length
  end
end

#cleanup_bone_refs(vertexes) ⇒ Object



922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
# File 'lib/bayonetta/wmb.rb', line 922

def cleanup_bone_refs(vertexes)
  if header.has_bone_refs != 0
    bone_refs_map = @bone_refs.each_with_index.collect { |b, i| [i, b] }.to_h
    used_bone_refs_indexes = vertex_indices.collect { |vi| vertexes[vi].bone_infos.get_indexes }.flatten.uniq
    new_bone_refs_list = used_bone_refs_indexes.collect{ |i| bone_refs_map[i] }.uniq.sort
    new_bone_refs_reverse_map = new_bone_refs_list.each_with_index.collect { |b, i| [b, i] }.to_h
    translation_map = used_bone_refs_indexes.collect { |ri|
      [ri, new_bone_refs_reverse_map[bone_refs_map[ri]]]
    }.to_h
    vertex_indices.uniq.sort.each { |vi| vertexes[vi].bone_infos.remap_indexes(translation_map) }
    @bone_refs = new_bone_refs_list
    @num_bone_ref = @bone_refs.length
  end
  self
end

#duplicate(positions, vertexes, vertexes_ex) ⇒ Object



853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
# File 'lib/bayonetta/wmb.rb', line 853

def duplicate(positions, vertexes, vertexes_ex)
  b = Batch::new
  if header.has_bone_refs != 0
    b.header = @header.dup
    b.num_bone_ref = @num_bone_ref
    b.bone_refs = @bone_refs.dup
  else
    b.unknown = @unknown
  end
  l = vertexes.length
  old_indices_map = vertex_indices.uniq.sort.each_with_index.collect { |vi, i| [vi, l + i] }.to_h
  old_indices_map.each { |vi, nvi| positions[nvi] = positions[vi] } if positions
  old_indices_map.each { |vi, nvi| vertexes[nvi] = vertexes[vi] }
  old_indices_map.each { |vi, nvi| vertexes_ex[nvi] = vertexes_ex[vi] } if vertexes_ex
  b.indices = vertex_indices.collect { |vi| old_indices_map[vi] }
  b.recompute_from_absolute_indices
  b
end

#filter_vertexes(vertexes) ⇒ Object



911
912
913
914
915
916
# File 'lib/bayonetta/wmb.rb', line 911

def filter_vertexes(vertexes)
  vertex_map = vertexes.collect { |i| [i, true] }.to_h
  trs = triangles
  new_trs = trs.select { |tr| vertex_map.include?(tr[0]) && vertex_map.include?(tr[1]) && vertex_map.include?(tr[2]) }
  set_triangles(new_trs)
end

#recompute_from_absolute_indicesObject



872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
# File 'lib/bayonetta/wmb.rb', line 872

def recompute_from_absolute_indices
  @header.num_indices = @indices.length
  unless @header.num_indices == 0
    sorted_indices = @indices.sort.uniq
    @header.vertex_start = sorted_indices.first
    @header.vertex_end = sorted_indices.last + 1
    if sorted_indices.last > 0xffff
      offset = @header.vertex_offset = @header.vertex_start
      @indices.collect! { |i| i - offset }
    else
      @header.vertex_offset = 0
    end
  end
  self
end

#set_triangles(trs) ⇒ Object



903
904
905
906
907
908
909
# File 'lib/bayonetta/wmb.rb', line 903

def set_triangles(trs)
  @header.primitive_type = 4
  @indices = trs.flatten
  recompute_from_absolute_indices
  @header.num_indices = @indices.length
  self
end

#trianglesObject



888
889
890
891
892
893
894
895
896
897
898
899
900
901
# File 'lib/bayonetta/wmb.rb', line 888

def triangles
  inds = @indices.collect{ |i| i + @header.vertex_offset }
  if @header.primitive_type == 4
    inds.each_slice(3).to_a
  else
    inds.each_cons(3).each_with_index.collect do |(v0, v1, v2), i|
      if i.even?
        [v0, v1, v2]
      else
        [v1, v0, v2]
      end
    end.select { |t| t.uniq.length == 3 }
  end
end

#vertex_indicesObject



918
919
920
# File 'lib/bayonetta/wmb.rb', line 918

def vertex_indices
  indices.collect { |i| i + @header.vertex_offset }
end