diff --git a/direct/src/actor/Actor.py b/direct/src/actor/Actor.py index 7c3a580b7c..e55dbdc0b5 100644 --- a/direct/src/actor/Actor.py +++ b/direct/src/actor/Actor.py @@ -159,6 +159,7 @@ class Actor(DirectObject, NodePath): self.__sortedLODNames = [] self.__animControlDict = {} self.__controlJoints = {} + self.__frozenJoints = {} self.__subpartsComplete = False @@ -310,6 +311,14 @@ class Actor(DirectObject, NodePath): otherCopy = other.copyTo(self) self.setGeomNode(otherCopy.getChild(0)) + # copy the switches for lods + self.switches = other.switches + self.__LODNode = self.find('**/+LODNode') + self.__hasLOD = 0 + if (not self.__LODNode.isEmpty()): + self.__hasLOD = 1 + + # copy the part dictionary from other self.__copyPartBundles(other) self.__copySubpartDict(other) @@ -318,12 +327,6 @@ class Actor(DirectObject, NodePath): # copy the anim dictionary from other self.__copyAnimControls(other) - # copy the switches for lods - self.switches = other.switches - self.__LODNode = self.find('**/+LODNode') - self.__hasLOD = 0 - if (not self.__LODNode.isEmpty()): - self.__hasLOD = 1 def __cmp__(self, other): # Actor inherits from NodePath, which inherits a definition of @@ -630,7 +633,7 @@ class Actor(DirectObject, NodePath): specific geometry to. Returns 'None' if not found """ if self.__LODNode: - lod = self.__LODNode.find("**/" + str(lodName)) + lod = self.__LODNode.find("**/%s"%lodName) if lod.isEmpty(): return None else: @@ -1041,6 +1044,35 @@ class Actor(DirectObject, NodePath): return node + #This is an alternate method to control joints, which can be copied + #This function is optimal in a non control jointed actor + def freezeJoint(self, partName, jointName, lodName="lodRoot", pos=Vec3(0,0,0), hpr=Vec3(0,0,0), scale=Vec3(1,1,1)): + mat=Mat4(TransformState.makePosHprScale(pos,hpr,scale).getMat()) + + partBundleDict = self.__partBundleDict.get(lodName) + if not partBundleDict: + Actor.notify.warning("no lod named: %s" % (lodName)) + return None + + subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName)) + partDef = partBundleDict.get(subpartDef.truePartName) + if partDef: + bundle = partDef.partBundle + else: + Actor.notify.warning("no part named %s!" % (partName)) + return None + + joint = bundle.findChild(jointName) + if joint == None: + Actor.notify.warning("no joint named %s!" % (jointName)) + return None + + + if self.__frozenJoints.has_key(bundle.this): + self.__frozenJoints[bundle.this][jointName] = mat + else: + self.__frozenJoints[bundle.this] = { jointName: mat } + def instance(self, path, partName, jointName, lodName="lodRoot"): """instance(self, NodePath, string, string, key="lodRoot") Instance a nodePath to an actor part at a joint called jointName""" @@ -1625,7 +1657,7 @@ class Actor(DirectObject, NodePath): self.gotName = 1 # we rename this node to make Actor copying easier - bundleNP.node().setName(Actor.partPrefix + partName) + bundleNP.node().setName("%s%s"%(Actor.partPrefix,partName)) if (self.__partBundleDict.has_key(lodName) == 0): # make a dictionary to store these parts in @@ -1636,7 +1668,7 @@ class Actor(DirectObject, NodePath): if (lodName!="lodRoot"): # parent to appropriate node under LOD switch - bundleNP.reparentTo(self.__LODNode.find("**/" + str(lodName))) + bundleNP.reparentTo(self.__LODNode.find("**/%s"%lodName)) else: bundleNP.reparentTo(self.__geomNode) @@ -1884,7 +1916,6 @@ class Actor(DirectObject, NodePath): # copy of the bundle hierarchy, so we don't modify other # Actors that share the same bundle. animBundle = animBundle.copyBundle() - for jointName, node in controlDict.items(): if node: joint = animBundle.makeChildDynamic(jointName) @@ -1893,6 +1924,21 @@ class Actor(DirectObject, NodePath): else: Actor.notify.error("controlled joint %s is not present" % jointName) + #fix any other joints in place + fixDict = self.__frozenJoints.get(bundle.this, None) + if fixDict: + # Before we apply any control joints, we have to make a + # copy of the bundle hierarchy, so we don't modify other + # Actors that share the same bundle. + + animBundle = animBundle.copyBundle() + for jointName,mat in fixDict.items(): + joint = animBundle.makeChildDynamic(jointName) + if joint: + joint.setValue(mat) + else: + Actor.notify.error("controlled joint %s is not present" % jointName) + # bind anim animControl = bundle.bindAnim(animBundle, -1, subpartDef.subset) @@ -1918,7 +1964,7 @@ class Actor(DirectObject, NodePath): if lodName == 'lodRoot': partLod = self else: - partLod = self.find("**/" + lodName) + partLod = self.find("**/%s"%lodName) if partLod.isEmpty(): Actor.notify.warning("no lod named: %s" % (lodName)) return None @@ -1929,11 +1975,14 @@ class Actor(DirectObject, NodePath): assert partDef.partBundleNP.node().getNumBundles() == 1 # find the part in our tree - bundleNP = partLod.find("**/" + Actor.partPrefix + partName) + bundleNP = partLod.find("**/%s%s"%(Actor.partPrefix,partName)) if (bundleNP != None): # store the part bundle assert bundleNP.node().getNumBundles() == 1 bundle = bundleNP.node().getBundle(0) + otherFixed=other.__frozenJoints.get(partDef.partBundle.this,None) + if(otherFixed): + self.__frozenJoints[bundle.this]=otherFixed self.__partBundleDict[lodName][partName] = Actor.PartDef(bundleNP, bundle, model) else: Actor.notify.error("lod: %s has no matching part: %s" %