Browse Source

freeze joint functionality

Zachary Pavlov 18 years ago
parent
commit
777c080b9e
1 changed files with 61 additions and 12 deletions
  1. 61 12
      direct/src/actor/Actor.py

+ 61 - 12
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" %