比較バージョン

キー

  • この行は追加されました。
  • この行は削除されました。
  • 書式設定が変更されました。

...

...

...

...

...

For our first post, we are going to show you a fun hack: how to drive your agents with an XBox controller.

If you are not a technical user you can ignore the last section, download the material provided below and play with them in Maya 2017:

...

Atoms Crowdブログへようこそ。こちらのブログでは、Atomsをどのように使用できるかを説明するために、興味深い記事をいくつか投稿しています。

私たちの最初の投稿では、ユーザーに楽しいハックをご覧いただく予定です:XBox Controllerからユーザーのエージェントを動かす方法。

テクニカルユーザーではない場合は、最後のセクションは無視し、下にあるマテリアルをダウンロードして、Maya 2017でそれらを試してください。


...

ウィジェット コネクタ
width900
urlhttps://www.youtube.com/watch?v=49VHB27gREk
height500

How to run this example.

...

こちらの例の実行方法

  1. ユーザーのPythonパスの中にxbox.pydをコピーしてください。 (<ドライブ>:\ Documents and Settings \

  2. <username>
  3. <ユーザー名> \ My Documents \ maya \

  4. <Version>
  5. <バージョン> \

  6. scripts )
  7. scripts)

  8. Open the Atoms UI, create a new behaviour module and copy the content of the Xbox controller module in the editor. Click register.
  9. Create a new agent group, add a gridLayout module, a stateMachine module and the XBoxControllerModule .
  10. Set the time line frame range to 1 - 2000 .
  11. Copy the content of the Xbox module recorder in the script editor and run it.
  12. Click "Start".
  13. Use the Xbox controller to drive the agent.
  14. Click "Stop".

How does it work?

First of all, if you were doing all this by yourself you would need some C++ knowledge to capture the Xbox controller input and make it available in python. Luckily this has already been taken care of and you can access that information with the xbox.pyd module. If you are brave enough you can also have a look at the given Visual Studio project.

There are two other major components we are going to have a look now.

The XBoxControllerModule

...

  1. Atoms UIを開き、新しいBehaviourモジュールを作成して、Xbox Controllerモジュールのコンテンツをエディターにコピーします。

  2. 「Register」をクリックしてください。

  3. 新しいエージェントグループを作成して、gridLayoutモジュール、stateMachineモジュール、およびXBoxControllerモジュールを追加します。

  4. タイムラインフレームの範囲を1〜2000に設定します。

  5. Script EditorでXboxモジュールレコーダーの内容をコピーして実行します。

  6. 「Start」をクリックしてください。 Xbox Controllerを使用して、エージェントを操作してください。

  7. 「Stop」をクリックしてください。

...

どのように機能しますか?

まず最初に、ユーザー自身でこれをすべて実行している場合、ユーザーはXbox Controller inputを捉えて、Pythonで利用を可能にするためにC ++の知識がいくつか必要になります。

幸い、これは既に考慮されているため、ユーザーはxbox.pydモジュールからその情報へアクセスすることが可能です。

ユーザーに十分な意欲がある場合、ユーザーは与えられたビジュアルスタジオプロジェクトを確認することができます。現在、その他に2つの主要なコンポーネントがあります。

XBoxControllerModule

これはすべての作業を行い、XBox Controllerを使用して、ユーザーが実行するアクションをキャッシュするAtomsモジュールです。

コード ブロック
languagepy
linenumberstrue
import Atoms
import AtomsCore
import AtomsMath
import os
import xbox
import maya


class XBoxControllerModule(Atoms.BehaviourModule):
    def __init__(self):
        Atoms.BehaviourModule.__init__(self)

		# Adding the module metadatas
        self.addAttribute("cachedAngle", AtomsCore.Vector3Metadata(AtomsMath.V3d(0.0,0.0,0.0)))
        self.addAttribute("cachedState", AtomsCore.IntMetadata(0))
        self.addAttribute("record", AtomsCore.BoolMetadata(False))
        self.addAttribute("turnAngle", AtomsCore.DoubleMetadata(3.0))

		# initializing the class members
        self.state = 0
        self.old_state = 0
        self.old_dir = [0.0,0.0,0.0]
		# lists for caching the values
        self.stateKeys=[]
        self.angleKeys=[]

    def initSimulation(self, agentGroup):
        # Emptying the two lists and setting initial values
        self.stateKeys=[]
        self.angleKeys=[]
        
        self.angleKeys.append([maya.cmds.currentTime(q=1), [0.0,0.0,0.0]])
        self.stateKeys.append([maya.cmds.currentTime(q=1), 0])

    def initFrame(self, agents, agentGroup):
		# getting the module parameters
        turnAngle = self.attributes()["turnAngle"].value()
        record = self.attributes()["record"].value()

		# getting the xbox control state
        state = xbox.getControlState()
        angle = state["LX"]
        buttonA = state["A"]
        buttonB = state["B"]
        buttonX = state["X"]
        
		# finding the right state depending on the pressed button
        if buttonA:
            self.state = 0
        if buttonB:
            self.state = 1
        if buttonX:
            self.state = 2
        
        if record:
			# if we are recording we cache the values
            if self.old_dir[0] != state["LX"] or self.old_dir[1] != state["LY"]:
                self.angleKeys.append([maya.cmds.currentTime(q=1), [state["LX"],state["LY"],0.0]])
            if self.state != self.old_state:
                self.stateKeys.append([maya.cmds.currentTime(q=1), self.state])
            self.old_dir = [state["LX"],state["LY"],0.0]
            self.old_state = self.state
        else:
			# otherwise we get the default values from the module parameters
            angle = self.attributes()["cachedAngle"].value().x
            self.state = self.attributes()["cachedState"].value()
            
		# for each agent changing the state and direction
        for agent in agents:
            if self.state:
                agent.metadata()["state"].set(self.state)
            dir = agent.metadata()["direction"].value()
            q = AtomsMath.Quatd()
            q.setAxisAngle(AtomsMath.V3d(0.0,1.0,0.0), -angle * turnAngle * 3.1456 / 180.0)
            dir = dir * q.toMatrix44()
            agent.metadata()["direction"].set(dir)

    def endSimulation(self, agents, agentGroup):
        # setting all the keyframes		
        for v in self.angleKeys:
            maya.cmds.setKeyframe(agentGroup.name() + ".atoms_XBoxControllerModule_cachedAngle.atoms_XBoxControllerModule_cachedAngleX",v=v[1][0],t=[v[0]])
            maya.cmds.setKeyframe(agentGroup.name() + ".atoms_XBoxControllerModule_cachedAngle.atoms_XBoxControllerModule_cachedAngleY",v=v[1][1],t=[v[0]])
            maya.cmds.setKeyframe(agentGroup.name() + ".atoms_XBoxControllerModule_cachedAngle.atoms_XBoxControllerModule_cachedAngleZ",v=v[1][02],t=[v[0]])
        for v in self.stateKeys:
            maya.cmds.setKeyframe(agentGroup.name() + ".atoms_XBoxControllerModule_cachedState",v=v[1],t=[v[0]])
            

...


Xbox module recorder

...

これは、記録を開始/停止するためのシンプルなPySide UIです。こちらのスクリプトを実行する前に、必ずエージェントグループトランスフォームを選択してください。

コード ブロック
languagepy
linenumberstrue
import AtomsMaya
import maya


from PySide2 import QtWidgets, QtCore, QtGui

class XboxControllerModuleWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(XboxControllerModuleWidget, self).__init__(parent)
        self.ag_name = maya.cmds.ls(sl=1,dag=1,lf=1,shapes=1)[0]
        self.v_layout = QtWidgets.QVBoxLayout()
        self.start = QtWidgets.QPushButton("Start")
        self.stop = QtWidgets.QPushButton("Stop")
        self.v_layout.addWidget(self.start)
        self.v_layout.addWidget(self.stop)        
        self.setLayout(self.v_layout)
        
        self.start.clicked.connect(self._start)
        self.stop.clicked.connect(self._stop)
        self.start.setEnabled(True)
        self.stop.setEnabled(False)
        
    def _start(self):
        ag_name = self.ag_name
        maya.cmds.setAttr(ag_name + ".atoms_XBoxControllerModule_record",1)
        maya.mel.eval("playButtonStart;")
        maya.mel.eval("playButtonForward;")
        self.start.setEnabled(False)
        self.stop.setEnabled(True)
        
    def _stop(self):
        ag_name = self.ag_name
        ag = AtomsMaya.getAgentGroup(ag_name)
        mod = ag.behaviourModule("XBoxControllerModule")
        mod.endSimulation(ag.agents(), ag)
        maya.cmds.setAttr(ag_name + ".atoms_XBoxControllerModule_record",0)
        maya.mel.eval("playButtonForward;")
        self.start.setEnabled(True)
        self.stop.setEnabled(False)
        
w = XboxControllerModuleWidget()
w.show()        

...