概要

私がPanda3Dを使ってきてつまづいたりした所の解決策を解説します。この記事は今後アップデートされるかもしれません。

この記事で使用しているツールのバージョン: Windows 10, Panda3D: 1.10.14, Python: 3.12.3

Panda3Dの基本的な使い方は、以下などを参照。

Programming with Panda3D — Panda3D
Manual

Python+Panda3Dによるゲームプログラミング入門 Panda3Dゲームエンジンのテキストブック | 多田 憲孝 |本 | 通販 | Amazon
※アソシエイトリンクです。

基本

base とは ShowBase のインスタンスのこと。
ShowBase を継承したクラスでは self がそのまま base と同じ役割を持つ。

from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        #以下アプリの準備
        #例 selfをbaseに変更しても可
        self.setFrameRateMeter(True)
        base.setFrameRateMeter(True)
        model = self.loader.loadModel(f"model.egg", noCache=True)
        model = base.loader.loadModel(f"model.egg", noCache=True)

if __name__ == "__main__":
    app = MyApp()
    app.run()

ファイルの読み込み

絶対パス

Panda3Dでは絶対パスをvfs形式(Linux形式)で書かないと失敗することがあります。

Windowsでは "D:/path/to/file.gltf" のように書くのが一般的ですが、
Panda3Dでは "/d/path/to/file.gltf" といったように、"D:"を"/d"にします。

model = self.loader.loadModel("D:/resource/model.gltf") #エラー
model = self.loader.loadModel("/d/resource/model.gltf") #OK

相対パス

Panda3D の相対パスは「Python の カレントディレクトリ」を基準に解決されます。
しかし VSCode や PyCharm の実行設定によっては カレントディレクトリ が自動的に main.py の場所になる場合があります。
Python組み込み関数(open()など)とPanda3Dの基準ディレクトリがずれることがあります。

例えばファイル階層が以下の時、

root/
    └ resource/
        └ image.png
    └ src/
        └ project-name/
            └ main.py

image.pngを読み込むには、以下のように書きます。

image = self.loader.loadTexture("resource/image.png") #rootが基準の場合
image = self.loader.loadTexture("../../resource/image.png") #main.pyが基準の場合

絶対パス、相対パスの仕組みはややこしいので、以下のような、どこからでも絶対パスを返す、PathManagerを作ると良いでしょう。

root/
    └ resource/
        └ image.png
    └ src/
        └ project-name/
            └ main.py
            └ shared/
                └ util/
                    └ path_manager.py
from pathlib import Path
import re

class PathManager:
    PROJECT_ROOT = Path(__file__).resolve().parents[4] #path_manager.pyから5つ上の階層

    RESOURCE_DIR = PROJECT_ROOT / "resources"

    @staticmethod
    def to_vfs(path: Path) -> str:
        """
        Windows の絶対パスを Panda3D VFS 形式に変換する
        例: D:/path/to/file → /d/path/to/file
        """
        posix = path.as_posix()

        # Windows ドライブレターを検出
        match = re.match(r"([A-Za-z]):/(.*)", posix)
        if match:
            drive = match.group(1).lower()
            rest = match.group(2)
            return f"/{drive}/{rest}"

        return posix  # もともと UNIX 形式ならそのまま

    @classmethod
    def resource(cls, *paths: str):
        p = cls.RESOURCE_DIR.joinpath(*paths)
        return p

    @classmethod
    def resource_vfs(cls, *paths: str):
        p = cls.RESOURCE_DIR.joinpath(*paths)
        return cls.to_vfs(p)

使い方

path = PathManager.resource_vfs("image.png")
self.loader.loadTexture(path)

キャッシュ

モデルやテクスチャなどを変更しても反映されない場合、キャッシュが残っているからかもしれない。

windowsの場合、キャッシュは以下に保存されているので、必要があれば削除する。

C:\Users\You\AppData\Local\Panda3D-1.10\cache

また、読み込むときにnoCache引数をTrueにすると、キャッシュを読み込まなくなる。(キャッシュが削除されるわけではない)

model = self.loader.loadModel(f"model.egg", noCache=True)

参考: Clearing Cached Models - Pipeline - Panda3D

フレームレート制限

from ctypes import windll
windll.winmm.timeBeginPeriod(1) #精度を上げる

from panda3d.core import ClockObject
globalClock = ClockObject.getGlobalClock()
globalClock.setMode(ClockObject.M_limited)
globalClock.setFrameRate(24) #24fpsに制限

windllについて

デフォルトのWindowsのタイマーの精度は、細かい計算をするのには悪い。
BiginPeriodで精度を上げる。

参考: 【Solved】Limited framerate is not stable - Scripting Issues - Panda3D

レンダリング

座標系

Panda3Dは「右手座標」「Z-up」です。
オイラー角は node_path.setHpr(h, p, r) で指定します(H=Z軸、P=X軸、R=Y軸)。

カメラとサンライトのデフォルトの方向

回転がない時、+Y軸の方向を向いています。

透明

node_path.setTransparency(TransparencyAttrib.MAlpha)
node_path.setAlphaScale(0.5)

透明オブジェクトの中にさらに透明を描画したい場合は、MDualにする?

node_path.setTransparency(TransparencyAttrib.MDual)

参考: TransparencyAttrib — Panda3D Manual

デバッグ

フレームレートの表示

self.setFrameRateMeter(True)

アナライザーの表示

現在のオブジェクトの数、頂点数などが分かる

self.setSceneGraphAnalyzerMeter(True)

その他(宣伝)

私の作品を見て頂けるとうれしいです。

YouTube

【Multiply or Release】やさしくかがやく色塗りバトル - YouTube

ニコニコ動画

黒白の縄張りバトル - Multiply or Release 3D (Python / Panda3D)

検索用キーワード

Python Panda3D 自作ゲーム