[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3310] trunk/py/scripts/addons/ io_export_unreal_psk_psa.py: clean up script and updated.

John Phan darkneter at gmail.com
Thu Apr 26 07:42:52 CEST 2012


Revision: 3310
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=3310
Author:   darknet
Date:     2012-04-26 05:42:51 +0000 (Thu, 26 Apr 2012)
Log Message:
-----------
clean up script and updated. still need get some bugs out a a bit.

Modified Paths:
--------------
    trunk/py/scripts/addons/io_export_unreal_psk_psa.py

Modified: trunk/py/scripts/addons/io_export_unreal_psk_psa.py
===================================================================
--- trunk/py/scripts/addons/io_export_unreal_psk_psa.py	2012-04-26 01:56:25 UTC (rev 3309)
+++ trunk/py/scripts/addons/io_export_unreal_psk_psa.py	2012-04-26 05:42:51 UTC (rev 3310)
@@ -1,4 +1,4 @@
-#  ***** GPL LICENSE BLOCK *****
+#====================== BEGIN GPL LICENSE BLOCK ============================
 #
 #  This program is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -13,13 +13,15 @@
 #  You should have received a copy of the GNU General Public License
 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #  All rights reserved.
-#  ***** GPL LICENSE BLOCK *****
+#
+#======================= END GPL LICENSE BLOCK =============================
 
 bl_info = {
     "name": "Export Unreal Engine Format(.psk/.psa)",
     "author": "Darknet/Optimus_P-Fat/Active_Trash/Sinsoft/VendorX",
-    "version": (2, 5),
-    "blender": (2, 6, 3),
+    "version": (2, 4),
+    "blender": (2, 6, 2),
+    "api": 36079,
     "location": "File > Export > Skeletal Mesh/Animation Data (.psk/.psa)",
     "description": "Export Skeleletal Mesh/Animation Data",
     "warning": "",
@@ -77,16 +79,78 @@
 - http://sinsoft.com
 """
 
+
+#===========================================================================
+"""
+NOTES for Jan 2012 refactor (Spoof)
+
+	* THIS IS A WORK IN PROGRESS. These modifications were originally
+	intended for internal use and are incomplete. Use at your own risk! *
+
+TODO
+
+- (Blender 2.62) changes to Matrix math
+- (Blender 2.62) check for long names
+- option to manually set the root bone for export
+
+CHANGES
+
+- new bone parsing to allow advanced rigging
+- identification of armature and mesh
+- removed the need to apply an action to the armature
+- fixed anim rate to work correctly in UDK (no more FPS fudging)
+- progress reporting while processing smooth groups
+- more informative logging
+- code refactor for clarity and modularity
+	- naming conventions unified to use lowercase_with_underscore
+	- C++ datatypes and PSK/PSA classes remain CamelCaseStyle for clarity
+	- names such as 'ut' and 'unreal' unified to 'udk'
+	- simplification of code structure
+	- removed legacy code paths
+
+USAGE
+
+This version of the exporter is more selective over which bones are considered
+part of the UDK skeletal mesh, and allows greater flexibility for adding
+control bones to aid in animation.
+
+Taking advantage of this script requires the following methodology:
+
+	* Place all exportable bones into a bone hierarchy extending from a single
+	root. This root bone must have use_deform enabled. All other root bones
+	in the armature must disable use_deform. *
+
+The script searches for a root bone with use_deform set true and considers all
+bones parented to it as part of the UDK skeletal mesh. Thus only these bones
+are exported and all other bones are ignored.
+
+This removes many restrictions on the rigger/animator, who can add control
+bone hierarchies to the rig, and keyframe any element into actions. With this
+approach you can build complex animation rigs in a similar vein to the Rigify
+add-on, by Nathan Vegdahl. However...
+
+	* Rigify is incompatible with this script *
+
+Rigify interlaces deformer bones within a single hierarchy making it difficult
+to deconstruct for export. It also splits some meta-rig bones into multiple
+deformer bones (bad for optimising a game character). I had partial success
+writing a parser for the structure, but it was taking too much time and,
+considering the other issues with Rigify, it was abandoned.
+"""
+#===========================================================================
+
+
 import os
 import time
 import bpy
 import mathutils
 import random
 import operator
-import bmesh
+import sys
 
 from struct import pack
 
+
 # REFERENCE MATERIAL JUST IN CASE:
 # 
 # U = x / sqrt(x^2 + y^2 + z^2)
@@ -94,1772 +158,1719 @@
 #
 # Triangles specifed counter clockwise for front face
 #
-#defines for sizeofs
-SIZE_FQUAT = 16
-SIZE_FVECTOR = 12
-SIZE_VJOINTPOS = 44
-SIZE_ANIMINFOBINARY = 168
-SIZE_VCHUNKHEADER = 32
-SIZE_VMATERIAL = 88
-SIZE_VBONE = 120
-SIZE_FNAMEDBONEBINARY = 120
-SIZE_VRAWBONEINFLUENCE = 12
-SIZE_VQUATANIMKEY = 32
-SIZE_VVERTEX = 16
-SIZE_VPOINT = 12
-SIZE_VTRIANGLE = 12
-MaterialName = []
+# defines for sizeofs
+SIZE_FQUAT				= 16
+SIZE_FVECTOR			= 12
+SIZE_VJOINTPOS			= 44
+SIZE_ANIMINFOBINARY		= 168
+SIZE_VCHUNKHEADER		= 32
+SIZE_VMATERIAL			= 88
+SIZE_VBONE				= 120
+SIZE_FNAMEDBONEBINARY	= 120
+SIZE_VRAWBONEINFLUENCE	= 12
+SIZE_VQUATANIMKEY		= 32
+SIZE_VVERTEX			= 16
+SIZE_VPOINT				= 12
+SIZE_VTRIANGLE			= 12
 
-# ======================================================================
-# TODO: remove this 1am hack
-nbone = 0
-exportmessage = "Export Finish" 
-exportfile = True
-########################################################################
+MaterialName			= []
+
+
+#===========================================================================
+# Custom exception class
+#===========================================================================
+class Error( Exception ):
+
+	def __init__(self, message):
+		self.message = message
+
+
+#===========================================================================
+# Verbose logging with loop truncation
+#===========================================================================
+def verbose( msg, iteration=-1, max_iterations=4, msg_truncated="..." ):
+
+	if bpy.context.scene.udk_option_verbose == True:
+		# limit the number of times a loop can output messages
+		if iteration > max_iterations:
+			return
+		elif iteration == max_iterations:
+			print(msg_truncated)
+			return
+
+		print(msg)
+	
+
+#===========================================================================
+# Log header/separator
+#===========================================================================
+def header( msg, justify='LEFT', spacer='_', cols=78 ):
+	
+	if justify == 'LEFT':
+		s = '{:{spacer}<{cols}}'.format(msg+" ", spacer=spacer, cols=cols)
+	
+	elif justify == 'RIGHT':
+		s = '{:{spacer}>{cols}}'.format(" "+msg, spacer=spacer, cols=cols)
+	
+	else:
+		s = '{:{spacer}^{cols}}'.format(" "+msg+" ", spacer=spacer, cols=cols)
+	
+	return "\n" + s + "\n"
+
+
+#===========================================================================
 # Generic Object->Integer mapping
 # the object must be usable as a dictionary key
+#===========================================================================
 class ObjMap:
-    def __init__(self):
-        self.dict = {}
-        self.next = 0
-    def get(self, obj):
-        if obj in self.dict:
-            return self.dict[obj]
-        else:
-            id = self.next
-            self.next = self.next + 1
-            self.dict[obj] = id
-            return id
-        
-    def items(self):
-        getval = operator.itemgetter(0)
-        getkey = operator.itemgetter(1)
-        return map(getval, sorted(self.dict.items(), key=getkey))
+	
+	def __init__(self):
+		self.dict = {}
+		self.next = 0
+	
+	def get(self, obj):
+		if obj in self.dict:
+			return self.dict[obj]
+		else:
+			id = self.next
+			self.next = self.next + 1
+			self.dict[obj] = id
+			return id
+	
+	def items(self):
+		getval = operator.itemgetter(0)
+		getkey = operator.itemgetter(1)
+		return map(getval, sorted(self.dict.items(), key=getkey))
 
-########################################################################
+
+#===========================================================================
 # RG - UNREAL DATA STRUCTS - CONVERTED FROM C STRUCTS GIVEN ON UDN SITE 
 # provided here: http://udn.epicgames.com/Two/BinaryFormatSpecifications.html
 # updated UDK (Unreal Engine 3): http://udn.epicgames.com/Three/BinaryFormatSpecifications.html
+#===========================================================================
 class FQuat:
-    def __init__(self): 
-        self.X = 0.0
-        self.Y = 0.0
-        self.Z = 0.0
-        self.W = 1.0
-        
-    def dump(self):
-        data = pack('ffff', self.X, self.Y, self.Z, self.W)
-        return data
-        
-    def __cmp__(self, other):
-        return cmp(self.X, other.X) \
-            or cmp(self.Y, other.Y) \
-            or cmp(self.Z, other.Z) \
-            or cmp(self.W, other.W)
-        
-    def __hash__(self):
-        return hash(self.X) ^ hash(self.Y) ^ hash(self.Z) ^ hash(self.W)
-        
-    def __str__(self):
-        return "[%f,%f,%f,%f](FQuat)" % (self.X, self.Y, self.Z, self.W)
-        
+
+	def __init__(self): 
+		self.X = 0.0
+		self.Y = 0.0
+		self.Z = 0.0
+		self.W = 1.0
+		
+	def dump(self):
+		return pack('ffff', self.X, self.Y, self.Z, self.W)
+		
+	def __cmp__(self, other):
+		return cmp(self.X, other.X) \
+			or cmp(self.Y, other.Y) \
+			or cmp(self.Z, other.Z) \
+			or cmp(self.W, other.W)
+		
+	def __hash__(self):
+		return hash(self.X) ^ hash(self.Y) ^ hash(self.Z) ^ hash(self.W)
+		
+	def __str__(self):
+		return "[%f,%f,%f,%f](FQuat)" % (self.X, self.Y, self.Z, self.W)
+
+
 class FVector(object):
-    def __init__(self, X=0.0, Y=0.0, Z=0.0):
-        self.X = X
-        self.Y = Y
-        self.Z = Z
-        
-    def dump(self):
-        data = pack('fff', self.X, self.Y, self.Z)
-        return data
-        
-    def __cmp__(self, other):
-        return cmp(self.X, other.X) \
-            or cmp(self.Y, other.Y) \
-            or cmp(self.Z, other.Z)
-        
-    def _key(self):
-        return (type(self).__name__, self.X, self.Y, self.Z)
-        
-    def __hash__(self):
-        return hash(self._key())
-        
-    def __eq__(self, other):
-        if not hasattr(other, '_key'):
-            return False
-        return self._key() == other._key() 
-        
-    def dot(self, other):
-        return self.X * other.X + self.Y * other.Y + self.Z * other.Z
-    
-    def cross(self, other):
-        return FVector(self.Y * other.Z - self.Z * other.Y,
-                self.Z * other.X - self.X * other.Z,
-                self.X * other.Y - self.Y * other.X)
-                
-    def sub(self, other):
-        return FVector(self.X - other.X,
-            self.Y - other.Y,
-            self.Z - other.Z)
 
+	def __init__(self, X=0.0, Y=0.0, Z=0.0):
+		self.X = X
+		self.Y = Y
+		self.Z = Z
+		
+	def dump(self):
+		return pack('fff', self.X, self.Y, self.Z)
+		
+	def __cmp__(self, other):
+		return cmp(self.X, other.X) \

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list