SC2Mapster / m3addon

Blender Addon to import and export m3 files
GNU General Public License v2.0
49 stars 18 forks source link

Batch Conversion Scripts #8

Closed emnh closed 9 months ago

emnh commented 5 years ago

I have 2 small scripts for batch conversion from M3 to GLTF 2.0 via FBX using Blender and M3Addon and https://github.com/facebookincubator/FBX2glTF for 3D and ImageMagick to convert DDS to JPG. They are hackish and will need editing for binary locations before run, but would you like me to create a pull request? Put them in a batch/ folder? I'll just copy-paste them in the issue for now.

I also have a demo page that shows how to both skin and instance a GLTF 2.0 model for drawing mass quantities of units using THREE.js (1 million units (http://emh.lart.no/publish/csb/million-mutas2.png) at 3 FPS, 20k animated units with simple physics at 144 FPS on RTX 2080 Ti). This one is better kept as separate repository due to usefulness apart from M3 and because of a few dependencies and is not ready for publishing yet, but could be linked to later if you want to. Or people can just find it through the issue since I saw you do not have capacity for taking pull requests at the moment. I will post a link on this issue thread when I push it to github.

Script for batch conversion from FBX to GLTF 2.0. Run with blender -P or just let the other script call it.

batch_convert.py

import bpy
import os
import glob
import sys

print(sys.argv)
path = os.path.realpath(__file__)
#path = bpy.context.space_data.text.filepath

if not path:
    raise Exception("No script path. Run script with blender.exe -P batch_convert.py. Or edit path in script.")
    #raise Exception("Script file is not saved")

path = os.path.dirname(path)

for f in glob.glob(os.path.join(path, 'models\\*.m3')):
    fbxpath = f.replace('.m3', '.fbx')
    if not os.path.exists(fbxpath):
        print("Converting", f, 'to', fbxpath)
        bpy.ops.wm.read_homefile(use_empty=True)
        getattr(bpy.ops.m3,'import')(filepath=f)
        for img in bpy.data.images:
            img.filepath = img.filepath.replace('.dds', '.jpg')
            print("Replaced", img.filepath)
            img.reload()
        bpy.ops.export_scene.fbx(filepath=fbxpath)
    else:
        print("Skipping", f, 'because FBX exists')

Here is the main script, which searches for M3 files specified in $PWD/../../mods and converts them. Edit and use at will. I ran the script under Windows Subsystem for Linux on Windows. Should work on Linux as well if you replace the path to Blender. Also edit path to FBX2glTF-linux-x64 and m3addon.

assimilate.sh

#!/bin/bash

mkdir -p models
cd models

if [ ! -e "m3list.txt" ]; then
  # TODO: replace path below by path to extracted game files
  find $PWD/../../mods -name '*.m3' > m3list.txt
fi

# list of units to search for and convert
(cat << EOF
Marine
Ghost
EOF
) | while read name; do
  #fname=$(find $PWD/../mods -name "$name.m3" | head -1)
  fname=$(grep "/$name"'\.m3$' m3list.txt | head -1)
  echo "$name -> $fname"

  name="$name".m3

  if [ -e "$name" ]; then
    echo "Skipping $name"
    continue
  fi

  echo "Copying m3 file"
  cp -v $fname .
  echo "Converting to XML"
  ../m3addon/m3ToXml.py $name
  xmlname=$name.xml
  basedir=$(echo $fname | sed 's/Assets.*//')
  echo "Copying assets from $basedir"
  strings $xmlname | sed -n '/Assets/s/\s*<imagePath>\(.*\)<\/imagePath>\s*/\1/p' | while read fpath; do
    dpath=$(dirname $fpath)
    mkdir -v -p $dpath
    bname=$(basename $fpath | tr '[:upper:]' '[:lower:]')
    bnameJPG=$(basename $fpath | sed 's/\.dds$/.jpg/')
    source="$basedir/$dpath/$bname"
    if [ ! -e "$source" ]; then
      source=$(echo $source | sed 's/liberty\.sc2mod/core.sc2mod/')
    fi
    target="$dpath/$bnameJPG"
    echo "Copying DDS file $source to $dpath (for Blender texture load only)"
    cp -v $source $dpath/
    echo "Converting $source to $target"
    convert $source $target
  done
  sed -i 's/\.dds/.jpg/' $xmlname
  #../m3addon/xmlToM3.py $xmlname
  blender="/mnt/c/Program Files/Blender Foundation/Blender/blender.exe"
  "$blender" -b -P "../batch_convert.py"
  for fname in *.fbx; do
    glbBase=$(echo $fname | sed 's/\.fbx$//')
    if [ ! -e $glbBase.glb ]; then
      echo "Converting $fname to GLB"
      ../FBX2glTF-linux-x64 -i $fname -b -o $glbBase
    else
      echo "Skipped $fname to GLB because exists"
    fi
  done

done
Talv commented 5 years ago

That's interesting, but feels a little bit out of the scope of this project. Although I'm sure it would be useful to some people. If your scripts do not require any changes in codebase of m3addon, I think it would be better to off-load them to another repository.

We could add a section Tools & resources to README file, and link scripts like these, and pretty much anything that takes use of m3addon.