Blender-ZeroEngine-MSH2-Plugin/src_research_readme/blender_2.43_scripts/bpymodules/colladaImEx/helperObjects.py

306 lines
11 KiB
Python

# --------------------------------------------------------------------------
# Illusoft Collada 1.4 plugin for Blender
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2006: Illusoft - colladablender@illusoft.com
#
# 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
# the Free Software Foundation; either version 2 of the License,
# or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
import Blender
import collada
from Blender.Mathutils import *
debprn = 0 #False #--- print debug "print 'deb: ..."
class Armature(object):
# static vars
# A list of all created armatures
_armatures = dict()
def __init__(self, armatureBObject, daeNode):
self.armatureBObject = armatureBObject
self.blenderArmature = Blender.Armature.New()
self.armatureBObject.link(self.blenderArmature)
print self.armatureBObject
self.boneInfos = dict()
self.rootBoneInfos = dict()
# The real blender name of this armature
self.realName = None
self.deaNode = daeNode
def GetBlenderObject(self):
return self.armatureBObject
def GetBlenderArmature(self):
return self.blenderArmature
def HasBone(self, boneName):
return boneName in self.boneInfos
def AddNewBone(self, boneName, parentBoneName, daeNode):
# Create a new Editbone.
editBone = Blender.Armature.Editbone()
# Add the bone to the armature
self.blenderArmature.bones[boneName] = editBone
# Get the boneInfo for the parent of this bone. (if it exists)
parentBoneInfo = None
if not parentBoneName is None and parentBoneName in self.boneInfos:
parentBoneInfo = self.boneInfos[parentBoneName]
# Create a new boneInfo object
boneInfo = BoneInfo(boneName, parentBoneInfo, self, daeNode)
# Store the boneInfo object in the boneInfos collection of this armature.
self.boneInfos[boneName] = boneInfo
# If this bone has a parent, set it.
if not parentBoneName is None and parentBoneName in self.boneInfos:
parentBoneInfo = self.boneInfos[parentBoneName]
parentBoneInfo.childs[boneName] = boneInfo
editBone.parent = self.GetBone(parentBoneName)
##boneInfo.SetConnected()
else:
self.rootBoneInfos[boneName] = boneInfo
return boneInfo
def MakeEditable(self,makeEditable):
if makeEditable:
self.GetBlenderArmature().makeEditable()
else:
self.GetBlenderArmature().update()
def GetBone(self, boneName):
if boneName is None or not (boneName in self.blenderArmature.bones.keys()):
return None
else:
return self.blenderArmature.bones[boneName]
# Get the location of the armature (VECTOR)
def GetLocation(self):
return Vector(self.armatureBObject.loc).resize4D()
def GetTransformation(self):
return self.armatureBObject.matrix
def GetBoneInfo(self, boneName):
if boneName is None:
return None
else:
return self.boneInfos[boneName]
def GetBoneInfoFromJoint(self, jointName):
for boneInfo in self.boneInfos:
if boneInfo.jointName == jointName:
return boneInfo
return None
def GetJointList(self):
result = dict()
for boneInfo in self.boneInfos.values():
result[boneInfo.GetJointName()] = boneInfo
return result
#---CLASSMETHODS
# Factory method
def CreateArmature(cls,objectName,armatureName, realArmatureName, daeNode):
armatureBObject = armature_obj = Blender.Object.New ('Armature', objectName)
armatureBObject.name = str(realArmatureName)
armature = Armature(armatureBObject, daeNode)
armature.name = armatureName
cls._armatures[armatureName] = armature
return armature
CreateArmature = classmethod(CreateArmature)
def GetArmature(cls, armatureName):
return cls._armatures.setdefault(armatureName)
GetArmature = classmethod(GetArmature)
def FindArmatureWithJoint(cls, jointName):
for armature in cls._armatures.values():
jointList = armature.GetJointList()
if jointName in jointList:
return armature
return None
FindArmatureWithJoint = classmethod(FindArmatureWithJoint)
class BoneInfo(object):
def __init__(self, boneName, parentBoneInfo, armature, daeNode):
if debprn: print 'deb:class BoneInfo_INITIALIZE............' #--------
if debprn: print 'deb: boneName=', boneName #--------
if debprn: print 'deb: parentBoneInfo=', #--------
if parentBoneInfo: print parentBoneInfo.name #, parentBoneInfo #--------
else: print parentBoneInfo #--------
#if debprn: print 'deb: armature=', #--------
#if armature: print armature.name #, armature #--------
#else: print armature, #--------
self.name = boneName
self.parent = parentBoneInfo
self.armature = armature
self.childs = dict()
self.daeNode = daeNode
self.headTransformMatrix = None
self.tailTransformMatrix = None
self.localTransformMatrix = Matrix()
self.worldTransformMatrix = Matrix()
def GetBone(self):
return self.armature.GetBone(self.name)
def SetTail(self, tailLocVector):
if len(tailLocVector) == 4:
tailLocVector.resize3D()
self.GetBone().tail = tailLocVector
def GetTail(self):
return self.GetBone().tail
def SetHead(self, headLocVector):
if len(headLocVector) == 4:
headLocVector.resize3D()
self.GetBone().head = headLocVector
def GetHead(self):
return self.GetBone().head
def SetConnected(self):
self.GetBone().options = Blender.Armature.CONNECTED
def IsEnd(self):
return len(self.childs) == 0
def IsRoot(self):
return self.parent is None
def GetTailName(self):
return self.daeNode.name
def GetJointName(self):
return self.name
## if not self.parent is None:
## return self.parent.name
## else:
## return self.armature.name
class AnimationInfo(object):
_animations = dict()
def __init__(self, nodeId):
self.nodeId = nodeId
self.times = dict()
def GetTypes(self, daeNode):
types = []
if len(self.times) > 0:
for target in self.times.values()[0]:
ta = self.GetType(daeNode, target)
if ta[0] == collada.DaeSyntax.TRANSLATE and not Blender.Object.Pose.LOC in types:
types.append(Blender.Object.Pose.LOC)
elif ta[0] == collada.DaeSyntax.ROTATE and not Blender.Object.Pose.ROT in types:
types.append(Blender.Object.Pose.ROT)
#TODO: check if scale correct implemented
elif ta[0] == collada.DaeSyntax.SCALE and not Blender.Object.Pose.SCALE in types:
types.append(Blender.Object.Pose.SCALE)
return types
def GetType(self, daeNode, target):
ta = target.split('.', 1)
for t in daeNode.transforms:
if t[2] == ta[0]:
return [t[0], ta]
def CreateAnimations(cls, animationsLibrary, fps, axiss):
for daeAnimation in animationsLibrary.daeLibrary.items:
for channel in daeAnimation.channels:
# Get the id of the node
targetArray = channel.target.split("/", 1)
nodeId = targetArray[0]
targetId = targetArray[1]
# Get the animationInfo object for this node (or create a new one)
animation = cls._animations.setdefault(nodeId, AnimationInfo(nodeId))
#if debprn: print 'deb:helperObj.py:class AnimationInfo CreateAnimations() dir(animation)', dir(animation) #----------
# loop trough all samplers
sampler = None
if debprn: print 'deb:helperObj.py:class AnimationInfo CreateAnimations() \ndeb: channel.source= ', channel.source #----------
for s in daeAnimation.samplers:
#if debprn: print 'deb: sampler.id = ', s.id #----------
#if debprn: print 'deb: channel.source[1:]= ', channel.source[1:] #----------
#org if s.id == channel.source[1:]:
if s.id == channel.source:
sampler = s
# Get the values for all the inputs
if not sampler is None:
input = sampler.GetInput("INPUT")
inputSource = daeAnimation.GetSource(input.source)
if inputSource.techniqueCommon.accessor.HasParam("TIME") and len(inputSource.techniqueCommon.accessor.params) == 1:
if debprn: print 'deb: DDDDD getting target' #----------
output = sampler.GetInput("OUTPUT")
outputSource = daeAnimation.GetSource(output.source)
outputAccessor = outputSource.techniqueCommon.accessor
accessorCount = outputAccessor.count
accessorStride = outputAccessor.stride
interpolations = sampler.GetInput("INTERPOLATION")
interpolationsSource = daeAnimation.GetSource(interpolations.source)
if 0: #because probably interpolationsAccessor is identical to outputAccessor
interpolationsAccessor = interpolationsSource.techniqueCommon.accessor
accessorCount = interpolationsAccessor.count
accessorStride = interpolationsAccessor.stride
if debprn: print 'deb: outputSource.source.data: ', outputSource.source.data #----------
#if debprn: print 'deb: dir(outputAccessor.params): ', dir(outputAccessor.params) #----------
#if debprn: print 'deb: dir(outputAccessor.params[0]): ', str(outputAccessor.params[0]) #----------
times = [x*fps for x in inputSource.source.data]
if debprn: print 'deb: times=', times #---------
for timeIndex in range(len(times)):
time = animation.times.setdefault(times[timeIndex], dict())
target = time.setdefault(targetId, dict())
#interp = time.setdefault(targetId, dict())
#if debprn: print 'deb: accessorStride=', accessorStride #---------
value = []
for j in range(accessorStride):
#if debprn: print 'deb: timeIndex,j,data=',timeIndex, j, outputSource.source.data[timeIndex*accessorStride + j] #---------
#if debprn: print 'deb: outputAccessor.params[j]=',outputAccessor.params[j] #---------
#target[outputAccessor.params[j]] = outputSource.source.data[timeIndex*accessorStride + j]
value.append(outputSource.source.data[timeIndex*accessorStride + j])
if debprn: print 'deb: value=', value #---------
target[outputAccessor.params[0]] = value
#interp[outputAccessor.params[j]] = interpolationsSource.source.data[timeIndex*accessorStride + j]
if debprn: print 'deb: time=', time #---------
if debprn: print 'deb: target=', target #---------
#if debprn: print 'deb:helperObj.py: X X X X X X X X X class AnimationInfo CreateAnimations() animation=', animation #----------
CreateAnimations = classmethod(CreateAnimations)
def GetAnimationInfo(cls, nodeId):
for animation in cls._animations.values():
if animation.nodeId == nodeId:
return animation
return None
GetAnimationInfo = classmethod(GetAnimationInfo)