def qeyxz(q): iq = qinv(q) (xx, yy, zz) = qgetAxisZ(iq) s = 1.0 / max(1.0e-8, hypot(xx, zz)) xx *= s zz *= s ry = hou.hmath.radToDeg(-atan2(xx, zz)) rx = hou.hmath.radToDeg(asinSafe(yy)) qz = hou.Quaternion(rx, (1, 0, 0)) * hou.Quaternion(ry, (0, 1, 0)) v = qapply(qz, qgetAxisX(iq)) rz = hou.hmath.radToDeg(-atan2(v[1], v[0])) return [rx, ry, rz]
def qezyx(q): iq = qinv(q) (xx, yy, zz) = qgetAxisX(iq) s = 1.0 / max(1.0e-8, hypot(xx, yy)) xx *= s yy *= s rz = hou.hmath.radToDeg(-atan2(yy, xx)) ry = hou.hmath.radToDeg(asinSafe(zz)) qx = hou.Quaternion(ry, (0, 1, 0)) * hou.Quaternion(rz, (0, 0, 1)) v = qapply(qx, qgetAxisY(iq)) rx = hou.hmath.radToDeg(-atan2(v[2], v[1])) return [rx, ry, rz]
def qexzy(q): iq = qinv(q) (xx, yy, zz) = qgetAxisY(iq) s = 1.0 / max(1.0e-8, hypot(yy, zz)) yy *= s zz *= s rx = hou.hmath.radToDeg(-atan2(zz, yy)) rz = hou.hmath.radToDeg(asinSafe(xx)) qy = hou.Quaternion(rz, (0, 0, 1)) * hou.Quaternion(rx, (1, 0, 0)) v = qapply(qy, qgetAxisZ(iq)) ry = hou.hmath.radToDeg(-atan2(v[0], v[2])) return [rx, ry, rz]
def slerpParmTuple(tup, t1, t2, bias): if not isCompleteRotate(tup): raise hou.Error(str(tup) + " is not a value set of euler rotates") r1 = tup.evalAtFrame(t1) r2 = tup.evalAtFrame(t2) q1 = hou.Quaternion(hou.hmath.buildRotate(r1)) q2 = hou.Quaternion(hou.hmath.buildRotate(r2)) outq = q1.slerp(q2, bias) return tuple(outq.extractEulerRotates())
def qgetClosestXY(q): x = q[0] y = q[1] z = q[2] w = q[3] det = abs(-x * y - z * w) if det < 0.5: d = sqrt(abs(1.0 - 4.0 * det * det)) a = x * w - y * z b = w * w - x * x + y * y - z * z if b >= 0.0: s0 = a c0 = (d + b) * 0.5 else: s0 = (d - b) * 0.5 c0 = a ilen = rcp0(hypot(s0, c0)) s0 *= ilen c0 *= ilen s1 = y * c0 - z * s0 c1 = w * c0 + x * s0 ilen = rcp0(hypot(s1, c1)) s1 *= ilen c1 *= ilen x = s0 * c1 y = c0 * s1 z = -s0 * s1 w = c0 * c1 else: ilen = 1.0 / sqrt(det) x *= ilen y = 0.0 z = 0.0 w *= ilen return hou.Quaternion([x, y, z, w])
def _load_euler_quat(self, valParm, rOrd): self.type = ChTypes.QUATERNION frames = [] for i in xrange(0, self.size): for k in valParm[i].keyframes(): frames.append(k.frame()) frames = sorted(set(frames)) components = [] self.size = 4 for i in xrange(0, self.size): components.append(Component()) for frame in frames: v = [valParm[i].evalAtFrame(frame) for i in xrange(0, 3)] q = hou.Quaternion() q.setToEulerRotates(v, rOrd) for i in xrange(0, 4): c = components[i] kq = hou.Keyframe() kq.setFrame(frame) kq.setValue(q[i]) kq.setExpression("qlinear()", hou.exprLanguage.Hscript) c.keyframes.append(Component.Keyframe(kq)) self._set_components(components)
def writeTransformsStart(obj): mat = obj.worldTransform() #mat = mat.inverted() translates = mat.extractTranslates() translates[0] *= -1.0 # negate x coordinate rotates = mat.extractRotates() quat = hou.Quaternion(mat) angleAxis = quat.extractAngleAxis() translateString = '<transform translate="%s %s %s" >\n' % ( translates[0], translates[1], translates[2]) trzString = '\t<transform rotate="%s 0 0 1" >\n' % (rotates[2] * -1) if obj.type().name() == 'cam': tryString = '\t\t<transform rotate="%s 0 1 0" >\n' % ( (rotates[1] - 180) * -1) else: tryString = '\t\t<transform rotate="%s 0 1 0" >\n' % ( (rotates[1]) * -1) trxString = '\t\t\t<transform rotate="%s 1 0 0" >\n' % (rotates[0] * -1) transformsStringStart = translateString + trzString + tryString + trxString return transformsStringStart
def node_data(n): t = n.outputs()[0] q = hou.Quaternion() q.setToEulerRotates( (t.parm("rx").eval(), -t.parm("ry").eval(), -t.parm("rz").eval())) scl = hou.Vector3( (t.parm("sx").eval(), t.parm("sz").eval(), t.parm("sz").eval())) scl *= t.parm("scale").eval() attribs = [{ "name": "Is Enabled", "value": "true" }, { "name": "Name", "value": n.name()[5:] }, { "name": "Position", "value": str(-t.parm("tx").eval()) + " " + str(t.parm("ty").eval()) + " " + str(t.parm("tz").eval()) }, { "name": "Rotation", "value": str(q[3]) + " " + str(q[0]) + " " + str(q[1]) + " " + str(q[2]) }, { "name": "Scale", "value": str(scl[0]) + " " + str(scl[1]) + " " + str(scl[2]) }, { "name": "Variables" }] return attribs
def computeDirectionRotates(zDirection): zDirection = zDirection.normalized() if 1 - abs(AXIS_Y.dot(zDirection)) < EPSILON: quat = hou.Quaternion() quat.setToVectors(AXIS_Z, zDirection) return quat.extractEulerRotates() else: if zDirection.length() < EPSILON: zDirection = AXIS_Z z = zDirection y = hou.Vector3(0, 1, 0) x = y.cross(z) y = z.cross(x) mat = hou.Matrix4((x[0], x[1], x[2], 0, y[0], y[1], y[2], 0, z[0], z[1], z[2], 0, 0, 0, 0, 1)) return mat.extractRotates()
def set_world_space_rotation_and_translation_at_time( node_obj, time, rotation, translation): q = hou.Quaternion() q[0] = rotation[0] q[1] = rotation[1] q[2] = rotation[2] q[3] = rotation[3] m3 = q.extractRotationMatrix3() m4 = hou.Matrix4() for r in range(3): for c in range(3): m4.setAt(r, c, m3.at(r, c)) m4.setAt(3, 0, translation[0]) m4.setAt(3, 1, translation[1]) m4.setAt(3, 2, translation[2]) node_obj.setWorldTransform(m4) parms = ["tx", "ty", "tz", "rx", "ry", "rz"] for p in parms: parm = node_obj.parm(p) v = parm.eval() k = hou.Keyframe() k.setFrame(time) k.setValue(v) parm.setKeyframe(k)
def get_world_space_rotation_and_translation(node_obj): wm = node_obj.worldTransform() q = hou.Quaternion() q.setToRotationMatrix(wm) return (q[0], q[1], q[2], q[3]), (wm.at(3, 0), wm.at(3, 1), wm.at(3, 2))
def test_buildInstanceOrient(self): TARGET = hou.Matrix4( ((0.33212996389891691, 0.3465703971119134, -0.87725631768953083, 0.0), (-0.53068592057761732, 0.83754512635379064, 0.1299638989169675, 0.0), (0.77978339350180514, 0.42238267148014441, 0.46209386281588438, 0.0), (-1.0, 2.0, 4.0, 1.0))) mat = hou.hmath.buildInstance(hou.Vector3(-1, 2, 4), orient=hou.Quaternion( 0.3, -1.7, -0.9, -2.7)) self.assertEqual(mat, TARGET)
def processMesh(nodes, nodePieces, numPieces): PARMS = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'px', 'py', 'pz'] RFSTART = int(hou.expandString('$RFSTART')) RFEND = int(hou.expandString('$RFEND')) for frame in range(RFSTART, RFEND + 1): hou.setFrame(frame) print 'Processing Frame: {}'.format(frame) for objectToProcess in range(0, len(numPieces)): #If at the creation frame, skip keyframe if frame == nodes[objectToProcess].parm('createframe').eval(): continue for index in range(0, numPieces[objectToProcess]): for index_parm in range(0, 3): hou_keyed_parm = nodePieces[objectToProcess][index].parm( PARMS[index_parm]) hou_keyframe = hou.Keyframe() hou_keyframe.setFrame(frame) hou_keyframe.setValue( nodes[objectToProcess].simulation().findObject( nodes[objectToProcess].name()).geometry( ).iterPoints()[index].attribValue('P')[index_parm]) hou_keyed_parm.setKeyframe(hou_keyframe) for index_parm in range(0, 3): hou_keyed_parm = nodePieces[objectToProcess][index].parm( PARMS[index_parm + 3]) hou_keyframe = hou.Keyframe() hou_keyframe.setFrame(frame) hou_keyframe.setValue( hou.Quaternion( nodes[objectToProcess].simulation().findObject( nodes[objectToProcess].name()).geometry(). iterPoints()[index].attribValue( 'orient')).extractEulerRotates()[index_parm]) hou_keyed_parm.setKeyframe(hou_keyframe) print 'Processing Complete!'
def qinv(q): (x, y, z, w) = q return hou.Quaternion(-x, -y, -z, w)
def step(self): # update orientation accNorm = self.parent.angVelocity.length() accY = math.sin((accNorm * dt) / 2) accX = math.cos((accNorm * dt) / 2) eulerQuat = hou.Quaternion(accX, self.parent.angVelocity[0] * accY, self.parent.angVelocity[1] * accY, self.parent.angVelocity[2] * accY) qp = eulerQuat * self.parent.orientation self.orientation = qp # update acceleration orientQuat = qp * self.parent.orientation.inverse() angleAxis = orientQuat.extractAngleAxis() acc = angleAxis[0] * angleAxis[1] self.angVelocity = acc # update position self.position = (self.parent.position + self.parent.velocity * dt + (self.parent.angVelocity + gravity) * dt * dt) / 2.0 # update velocity self.velocity = (self.position - self.parent.position) / dt # surface adaptation if not len(surfaces): for surface in hou.node('/obj').selectedItems(): surfaces.append(surface.displayNode().geometry()) transform = hou.hmath.buildTranslate(surface.evalParm('tx'), surface.evalParm('ty'), surface.evalParm('tz')) rotate = hou.hmath.buildRotate(surface.evalParm('rx'), surface.evalParm('ry'), surface.evalParm('rz')) scale = hou.hmath.buildScale(surface.evalParm('sx'), surface.evalParm('sy'), surface.evalParm('sz')) transforms.append(scale * rotate * transform) for i in range(len(surfaces)): point = surfaces[i].nearestPoint(self.position * transforms[i].inverted(), max_radius=3.0) if point is not None: surfaceVec = point.position() * transforms[i] - self.position axis = surfaceVec.cross(self.velocity) angle = surfaceVec.dot(self.velocity) * adaptationStrength * dt self.orientation = hou.Quaternion(angle, axis) bounds = surfaces[i].boundingBox() minBounds = bounds.minvec() * transforms[i] maxBounds = bounds.maxvec() * transforms[i] xmin = minBounds[0] ymin = minBounds[1] zmin = minBounds[2] xmax = maxBounds[0] ymax = maxBounds[1] zmax = maxBounds[2] bounds.setTo((xmin, ymin, zmin, xmax, ymax, zmax)) if bounds.contains(self.position): parentDir = (self.parent.position - self.position).normalized() while (bounds.contains(self.position)): self.position += 0.1 * parentDir self.geo = self.createGeom()
def qgetClosestZY(q): qxy = qgetClosestXY(hou.Quaternion([q[1], q[2], -q[0], q[3]])) return hou.Quaternion([-qxy[2], qxy[0], qxy[1], qxy[3]])
def qget(r): return (hou.Quaternion(r[0], (1, 0, 0)), hou.Quaternion(r[1], (0, 1, 0)), hou.Quaternion(r[2], (0, 0, 1)))
import hou import math sceneRoot = hou.node('obj') # simulation starting values numIterations = 25 dt = 0.1 gravity = hou.Vector3(0, -9.8, 0) nodes = [] velocity = hou.Vector3(0.0, 0.2, 0.0) angVelocity = hou.Vector3(0.5, 0.0, 0.0) orientation = hou.Quaternion(0.2, 0.0, 0.0, 0.0) adaptationStrength = 0.9 surfaces = [] transforms = [] class Node: def __init__(self, count, parent=None, position=hou.Vector3(0, 0, 0)): self.parent = parent self.position = position self.velocity = velocity self.angVelocity = angVelocity self.orientation = orientation if parent is not None: self.group = [parent, self] else: self.group = [self] self.count = count self.geo = None