Last active
August 29, 2015 14:01
-
-
Save jelster/e1cc34e3303dacaad36f to your computer and use it in GitHub Desktop.
MWO Asset Scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Function Get-MwoBlenderMech | |
{ | |
[CmdletBinding()] | |
param( | |
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline=$true)] | |
[Alias('Family')] | |
[Alias('Chassis')] | |
[string[]]$MechFamily, | |
[Parameter(Position=1, Mandatory=$false, valuefrompipeline=$false)] | |
[Alias('Path')] | |
[string]$BaseDirectory = ".\", | |
[Parameter(Position=2, Mandatory=$false, ValueFromPipeline=$false)] | |
[string]$UsePngImageFormat = $False | |
) | |
process { | |
# Python commands used by Blender | |
$scriptimport = "bpy.ops.import_scene.obj" | |
$scriptscene = "bpy.context.scene.objects.active" | |
$scriptrotationmode = "bpy.context.active_object.rotation_mode=`"QUATERNION`"" | |
$scriptrotation = "bpy.context.active_object.rotation_quaternion" | |
$scripttransform = "bpy.ops.transform.translate" | |
$scriptremovedoubles = "bpy.ops.mesh.remove_doubles()" | |
$scripttristoquads = "bpy.ops.mesh.tris_convert_to_quads()" | |
$scriptseteditmode = "bpy.ops.object.mode_set(mode = `"EDIT`")" | |
$scriptsetobjectmode = "bpy.ops.object.mode_set(mode = `"OBJECT`")" | |
$scriptclearmaterial = "bpy.context.object.data.materials.clear()" #only works with 2.69 or newer | |
function getImagePath([string]$file) { | |
$imgExten = $file.replace(".tif","$imageformat").replace(".dds",".$imageformat") | |
if (!(test-path "$basedir\$imgExten")) { | |
return "" | |
} | |
$imgPath = resolve-path ("$basedir\$imgExten") | |
return $imgPath.Path.replace("\", "\\") | |
} | |
foreach($mech in $MechFamily) { | |
if ($UsePngImageFormat[0] -eq $True) { | |
$imageformat = ".png" | |
} | |
else { | |
$imageformat = ".jpg" | |
} | |
$basedir = (resolve-path $BaseDirectory).Path | |
$objectDir = Join-Path -Path $baseDir -ChildPath "objects" | |
$modeldir = Join-Path -Path $objectDir -ChildPath "mechs\$mech" | |
$mechFile = Join-Path -Path $modelDir -ChildPath ($mech + ".cdf") | |
$modeldir = $modeldir.replace("\","\\") # convert the path so it can be used by Blender | |
$bodyDir = join-path -Path $modelDir "body" | |
$basedir = $basedir.Replace("\","\\") | |
write-Debug "Mech is $mech" | |
Write-Debug "Image format $imageformat" | |
write-debug "Converted paths $basedir" | |
Write-Debug "Model directory is $modeldir" | |
Write-Debug "path to .CDF is $mechFile" | |
write-debug "path to body is $bodyDir" | |
if (!(test-path $mechFile)) { | |
write-error "Unable to find the input .cdf file: $mechFile" | |
continue | |
} | |
[xml]$cdffile = get-content $mechFile | |
$mechFile = $mechFile.replace("\","\\") | |
$importBuilder = new-object System.Text.StringBuilder | |
# TODO: guard clauses around calls to Get-Content | |
# *** MATERIALS *** | |
# Load up materials from the <mech_body.mtl> file | |
# Assumptions: The .cdf file we read has the name of the mech in it, and the mtl file is <mech>_body.mtl under the body subdirectory. | |
# For the cockpit, the mtl file is <mech>_a_cockpit_standard, and under the cockpit_standard subdir. | |
[xml]$matfile = get-content (resolve-path ("$bodyDir\\$mech" + "_body.mtl")) | |
[xml]$matcockpitfile = Get-Content (resolve-path("$modeldir\cockpit_standard\$mech" + "_a_cockpit_standard.mtl")) | |
# Set Blender to Cycles | |
write-progress $importBuilder.AppendLine("bpy.context.scene.render.engine = 'CYCLES'").Length | |
Write-Debug "Processing materials" | |
# Get the 4 materials from $matfile and create them in Blender | |
# material append wants an object of type material, not a string. Will have to generate that. | |
# Since we can't really generate a node layout at this time, we're just going to open the image files | |
# so it's easier for the user to generate. | |
$matfile.Material.SubMaterials.Material | % { | |
$matname = $_.Name # $matname is the name of the material | |
write-Debug "material $matname" | |
write-progress $importBuilder.AppendLine("$matname=bpy.data.materials.new('$matname')").Length | |
write-progress $importBuilder.AppendLine("$matname.use_nodes=True").Length | |
write-progress $importBuilder.AppendLine("$matname.active_node_material").Length | |
write-progress $importBuilder.AppendLine("TreeNodes = $matname.node_tree").Length | |
write-progress $importBuilder.AppendLine("links = TreeNodes.links").Length | |
write-progress $importBuilder.AppendLine("for n in TreeNodes.nodes:").Length | |
write-progress $importBuilder.AppendLine(" TreeNodes.nodes.remove(n)").Length | |
write-progress $importBuilder.AppendLine("").Length | |
#TODO check file existence (applies to all) | |
$_.textures.Texture | % { | |
write-debug "Texture $_.Map defines $_.File" | |
if ( $_.Map -eq "Diffuse") { | |
$matdiffuse = getImagePath($_.file).replace("/","\\") #assumes diffuse is in slot 0 | |
write-progress $importBuilder.AppendLine("matDiffuse = bpy.data.images.load(filepath=`"$matdiffuse`")").Length | |
write-progress $importBuilder.AppendLine("shaderDiffuse=TreeNodes.nodes.new('ShaderNodeBsdfDiffuse')").Length | |
write-progress $importBuilder.AppendLine("shaderMix=TreeNodes.nodes.new('ShaderNodeMixShader')").Length | |
write-progress $importBuilder.AppendLine("shout=TreeNodes.nodes.new('ShaderNodeOutputMaterial')").Length | |
write-progress $importBuilder.AppendLine("shaderDiffImg=TreeNodes.nodes.new('ShaderNodeTexImage')").Length | |
write-progress $importBuilder.AppendLine("shaderDiffImg.image=matDiffuse").Length | |
write-progress $importBuilder.AppendLine("shaderDiffuse.location = 100,500").Length | |
write-progress $importBuilder.AppendLine("shout.location = 500,400").Length | |
write-progress $importBuilder.AppendLine("shaderMix.location = 300,500").Length | |
write-progress $importBuilder.AppendLine("shaderDiffImg.location = -100,500").Length | |
write-progress $importBuilder.AppendLine("links.new(shaderDiffuse.outputs[0],shaderMix.inputs[1])").Length | |
write-progress $importBuilder.AppendLine("links.new(shaderMix.outputs[0],shout.inputs[0])").Length | |
write-progress $importBuilder.AppendLine("links.new(shaderDiffImg.outputs[0],shaderDiffuse.inputs[0])").Length | |
} | |
if ($_.Map -eq "Specular") { | |
$matspec = getImagePath($_.file).replace("/","\\") | |
write-progress $importBuilder.AppendLine("matSpec=bpy.data.images.load(filepath=`"$matspec`")").Length | |
write-progress $importBuilder.AppendLine("shaderSpec=TreeNodes.nodes.new('ShaderNodeBsdfGlossy')").Length | |
write-progress $importBuilder.AppendLine("shaderSpecImg=TreeNodes.nodes.new('ShaderNodeTexImage')").Length | |
write-progress $importBuilder.AppendLine("shaderSpecImg.image=matSpec").Length | |
write-progress $importBuilder.AppendLine("shaderSpec.location = 100,300").Length | |
write-progress $importBuilder.AppendLine("shaderSpecImg.location = -100,300").Length | |
write-progress $importBuilder.AppendLine("links.new(shaderSpec.outputs[0],shaderMix.inputs[2])").Length | |
write-progress $importBuilder.AppendLine("links.new(shaderSpecImg.outputs[0],shaderSpec.inputs[0])").Length | |
} | |
if ($_.Map -eq "Bumpmap") { | |
$matnormal = getImagePath($_.file).replace("/", "\\") | |
write-progress $importBuilder.AppendLine("matNormal=bpy.data.images.load(filepath=`"$matnormal`")").Length | |
write-progress $importBuilder.AppendLine("shaderNormalImg=TreeNodes.nodes.new('ShaderNodeTexImage')").Length | |
write-progress $importBuilder.AppendLine("shaderRGBtoBW=TreeNodes.nodes.new('ShaderNodeRGBToBW')").Length | |
write-progress $importBuilder.AppendLine("shaderNormalImg.image=matNormal").Length | |
write-progress $importBuilder.AppendLine("shaderNormalImg.location = -100,100").Length | |
write-progress $importBuilder.AppendLine("shaderRGBtoBW.location = 100,100").Length | |
write-progress $importBuilder.AppendLine("links.new(shaderNormalImg.outputs[0],shaderRGBtoBW.inputs[0])").Length | |
write-progress $importBuilder.AppendLine("links.new(shaderRGBtoBW.outputs[0],shout.inputs[2])").Length | |
} | |
} | |
} | |
Write-debug "Processing cockpit materials" | |
$matcockpitfile.Material.SubMaterials.Material | % { | |
$matname = $_.Name | |
write-progress $importBuilder.AppendLine("$matname=bpy.data.materials.new('$matname')").Length | |
write-progress $importBuilder.AppendLine("$matname.use_nodes=True").Length | |
write-progress $importBuilder.AppendLine("$matname.active_node_material").Length | |
write-progress $importBuilder.AppendLine("TreeNodes = $matname.node_tree").Length | |
write-progress $importBuilder.AppendLine("links = TreeNodes.links").Length | |
write-progress $importBuilder.AppendLine("for n in TreeNodes.nodes:").Length | |
write-progress $importBuilder.AppendLine(" TreeNodes.nodes.remove(n)").Length | |
write-progress $importBuilder.AppendLine("").Length | |
$_.textures.Texture | % { | |
if ( $_.Map -eq "Diffuse") { | |
$matdiffuse = getImagePath($_.file).replace("/", "\\") | |
if ( $_.File.Contains("@") ) { | |
#fixes monitor materials where it assigns a file that doesn't exist | |
$matdiffuse = "$basedir\\libs\\UI\\HUD\\Screens\\Monitors\\killcount_i7$imageFormat" | |
} | |
write-progress $importBuilder.AppendLine("matDiffuse = bpy.data.images.load(filepath=`"$matdiffuse`")" ).Length | |
write-progress $importBuilder.AppendLine("shaderDiffuse=TreeNodes.nodes.new('ShaderNodeBsdfDiffuse')" ).Length | |
write-progress $importBuilder.AppendLine("shaderMix=TreeNodes.nodes.new('ShaderNodeMixShader')" ).Length | |
write-progress $importBuilder.AppendLine("shout=TreeNodes.nodes.new('ShaderNodeOutputMaterial')" ).Length | |
write-progress $importBuilder.AppendLine("shaderDiffImg=TreeNodes.nodes.new('ShaderNodeTexImage')" ).Length | |
write-progress $importBuilder.AppendLine("shaderDiffImg.image=matDiffuse" ).Length | |
write-progress $importBuilder.AppendLine("shaderDiffuse.location = 100,500" ).Length | |
write-progress $importBuilder.AppendLine("shout.location = 500,400" ).Length | |
write-progress $importBuilder.AppendLine("shaderMix.location = 300,500" ).Length | |
write-progress $importBuilder.AppendLine("shaderDiffImg.location = -100,500" ).Length | |
write-progress $importBuilder.AppendLine("links.new(shaderDiffuse.outputs[0],shaderMix.inputs[1])" ).Length | |
write-progress $importBuilder.AppendLine("links.new(shaderMix.outputs[0],shout.inputs[0])" ).Length | |
write-progress $importBuilder.AppendLine("links.new(shaderDiffImg.outputs[0],shaderDiffuse.inputs[0])" ).Length | |
} | |
if ($_.Map -eq "Specular") { | |
$matspec = getImagePath($_.file).replace("/", "\\") | |
write-progress $importBuilder.AppendLine("matSpec=bpy.data.images.load(filepath=`"$matspec`")" ).Length | |
write-progress $importBuilder.AppendLine("shaderSpec=TreeNodes.nodes.new('ShaderNodeBsdfGlossy')" ).Length | |
write-progress $importBuilder.AppendLine("shaderSpecImg=TreeNodes.nodes.new('ShaderNodeTexImage')" ).Length | |
write-progress $importBuilder.AppendLine("shaderSpecImg.image=matSpec" ).Length | |
write-progress $importBuilder.AppendLine("shaderSpec.location = 100,300" ).Length | |
write-progress $importBuilder.AppendLine("shaderSpecImg.location = -100,300" ).Length | |
write-progress $importBuilder.AppendLine("links.new(shaderSpec.outputs[0],shaderMix.inputs[2])" ).Length | |
write-progress $importBuilder.AppendLine("links.new(shaderSpecImg.outputs[0],shaderSpec.inputs[0])" ).Length | |
} | |
if ($_.Map -eq "Bumpmap") { | |
$matnormal = getImagePath($_.file).replace("/", "\\") | |
write-progress $importBuilder.AppendLine("matNormal=bpy.data.images.load(filepath=`"$matnormal`")" ).Length | |
write-progress $importBuilder.AppendLine("shaderNormalImg=TreeNodes.nodes.new('ShaderNodeTexImage')" ).Length | |
write-progress $importBuilder.AppendLine("shaderRGBtoBW=TreeNodes.nodes.new('ShaderNodeRGBToBW')" ).Length | |
write-progress $importBuilder.AppendLine("shaderNormalImg.image=matNormal" ).Length | |
write-progress $importBuilder.AppendLine("shaderNormalImg.location = -100,100" ).Length | |
write-progress $importBuilder.AppendLine("shaderRGBtoBW.location = 100,100" ).Length | |
write-progress $importBuilder.AppendLine("links.new(shaderNormalImg.outputs[0],shaderRGBtoBW.inputs[0])" ).Length | |
write-progress $importBuilder.AppendLine("links.new(shaderRGBtoBW.outputs[0],shout.inputs[2])" ).Length | |
} | |
} | |
} | |
Write-debug "Parsing .OBJ" | |
# *** PARSING OBJs *** | |
# Start parsing out $mechline | |
$cdffile.CharacterDefinition.attachmentlist.Attachment | % { | |
#TODO: If you're reading a .cdf file here, it's recursive and you'll have to load in a few more files. For now, just replace to .obj | |
# for basic cockpit. | |
$aname = $_.AName | |
$rotation = $_.Rotation | |
$position = $_.Position | |
$bonename = $_.BoneName.replace(" ","_") | |
write-debug ("attachment file path $binding " + (Test-Path ($baseDirectory + "\" + $_.Binding))) | |
$binding = Get-Item -Path ($BaseDirectory + "\" + $_.Binding) | |
write-debug "value of Binding: $binding" | |
$binding_modified = $binding.FullName.replace(".cdf", ".obj").replace(".cga",".obj").replace(".cgf", ".obj").replace("\","\\") # For use by script | |
$flags = $_.Flags | |
if ($_.material) { # Material doesn't exist for every object. Don't set it if it doesn't. | |
$material = $_.Material | |
$matname = $material.split("/") | |
$matname = $matname[-1] | |
$material = $material.replace("/","\\") | |
} | |
# Figure out how to get the object name from $binding. | |
[string]$objectname = $binding.BaseName | |
# Time to generate the commands (in $parsedline, an array) | |
$parsedline = @() | |
# if it's a cockpit item, it'll have multiple groups. to avoid screwing up naming, we will import these keeping the vertex | |
# order with split_mode('OFF'). We do NOT want to remove doubles though, as this destroys the UVMap. | |
if ($objectname.Contains("cockpit")) { | |
$parsedline += $scriptimport + "(filepath='$binding_modified',use_groups_as_vgroups=True,split_mode=`'OFF`')" } | |
else { | |
$parsedline += $scriptimport + "(filepath='$binding_modified',use_groups_as_vgroups=True,split_mode=`'OFF`')" } | |
# set new object as the active object | |
$parsedline += $scriptscene + "=bpy.data.objects[`"$objectname`"]" | |
# Parent the object to the Armature: Assumes armature name is Armature and that it's been imported! | |
# $parsedline += $scriptscene + "=bpy.data.objects[`"Armature`"]" | |
# We may at this point (someday) to replace $objectname (above) with the $Aname, but for now let's stick with $objectname | |
$parsedline += $scriptrotationmode | |
$parsedline += $scriptrotation + "=[$rotation]" | |
$parsedline += $scripttransform + "(value=($position))" | |
$parsedline += $scriptclearmaterial | |
$parsedline += $scriptseteditmode | |
# Check to see if it's a cockpit item, and if so don't remove doubles! | |
if ($objectname -ne $null -and !$objectname.Contains("cockpit")) { | |
$parsedline += $scriptremovedoubles } | |
$parsedline += $scripttristoquads | |
# Create a vertex group with the bone name. This makes parenting to armature super easy! | |
$parsedline += "bpy.ops.object.vertex_group_add()" | |
$parsedline += "bpy.context.object.vertex_groups.active.name = `"$bonename`"" | |
$parsedline += "bpy.ops.mesh.select_all(action=`'SELECT`')" | |
$parsedline += "bpy.ops.object.vertex_group_assign()" | |
$parsedline += "bpy.ops.mesh.select_all(action=`'TOGGLE`')" | |
$parsedline += $scriptsetobjectmode | |
$parsedline += "bpy.context.object.data.materials.append($matname)" | |
foreach ($line in $parsedline ) { | |
write-progress $importBuilder.AppendLine($line).Length | |
} | |
} | |
Write-Output $importBuilder.ToString() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
usage: