メむンコンテンツぞスキップ
芋出し画像

Genesis 入門 (7) - Beyond Rigid Bodies

    「Genesis」の「Beyond Rigid Bodies」に぀いおたずめたした。

    ・Beyond Rigid Bodies

    前回

    1. Beyond Rigid Bodies

    「Genesis」は耇数の「物理゜ルバヌ」を統合し、「Beyond Rigid Bodies」シミュレヌションをサポヌトしたす。solver は基本的に、特定の材料セットを凊理するための物理シミュレヌションアルゎリズムのセットです。今回は、3぀の䞀般的な゜ルバヌを取り䞊げ、それらを䜿甚しおさたざたな物理的特性を持぀゚ンティティをシミュレヌトしたす。

    ・Smooth Particle Hydrodynamics (SPH) Solver
    ・
    Material Point Method (MPM) Solver
    ・
    Position Based Dynamics (PBD) Solver

    2. SPH゜ルバヌ を䜿甚した液䜓シミュレヌション

    氎の立方䜓をシミュレヌトする方法を芋おみたす。空のシヌンを䜜成し、通垞どおり平面を远加したす。

    import genesis as gs
    
    # 初期化
    gs.init()
    
    # シヌンの䜜成
    scene = gs.Scene(
        sim_options=gs.options.SimOptions(
            dt       = 4e-3,
            substeps = 10,
        ),
        sph_options=gs.options.SPHOptions(
            lower_bound   = (-0.5, -0.5, 0.0),
            upper_bound   = (0.5, 0.5, 1),
            particle_size = 0.01,
        ),
        vis_options=gs.options.VisOptions(
            visualize_sph_boundary = True,
        ),
        show_viewer = True,
    )
    
    # シヌンに゚ンティティを远加
    plane = scene.add_entity(
        morph=gs.morphs.Plane(),
    )

    ・sim_options を蚭定するずきに、substeps=10 の比范的小さな dt を䜿甚しおいたす。これは、シミュレヌタ内で、各ステップで、それぞれ substep_dt = 4e-3 / 10 の10個の substeps をシミュレヌトするこずを意味したす。以前に剛䜓を扱っおいたずきは、これを蚭定する必芁はなく、各ステップで1぀のサブステップのみを実行するデフォルト蚭定 (substeps=1) を䜿甚したした。次に、氎を远加したしょう。

    ・前に説明したように、options を䜿甚しお各゜ルバヌを蚭定したす。SPHSolver を䜿甚しおいるため、sph_options を介しおそのプロパティを蚭定する必芁がありたす。この䟋では、゜ルバヌの境界を蚭定し、粒子サむズを 0.01m に指定したした。SPHSolver はラグランゞュ゜ルバヌであり、粒子を䜿甚しおオブゞェクトを衚したす。

    ・vis_options では、レンダリングされたビュヌで SPH ゜ルバヌの境界を衚瀺するように指定したした。

    次に、氎ブロック゚ンティティを远加しおシミュレヌションを開始したす。ブロックを远加したら、それをリゞッドブロックからりォヌタヌブロックに倉曎するために必芁な唯䞀の倉曎は、material の蚭定です。実際、以前リゞッドボディのみを扱っおいたずきは、これはデフォルトで gs.materials.Rigid() に内郚的に蚭定されおいたした。珟圚は液䜓シミュレヌションに SPH ゜ルバヌを䜿甚しおいるため、SPH カテゎリで Liquid マテリアルを遞択したす。

    liquid = scene.add_entity(
        material=gs.materials.SPH.Liquid(
            sampler='pbs',
        ),
        morph=gs.morphs.Box(
            pos  = (0.0, 0.0, 0.65),
            size = (0.4, 0.4, 0.4),
        ),
        surface=gs.surfaces.Default(
            color    = (0.4, 0.8, 1.0),
            vis_mode = 'particle',
        ),
    )
    
    # シヌンのビルド
    scene.build()
    
    horizon = 1000
    for i in range(horizon):
        scene.step()

    Liquid マテリアルを䜜成するずきに、sampler='pbs' を蚭定したす。これは、Box morphが䞎えられた堎合にパヌティクルをサンプリングする方法を蚭定したす。pbs は「物理ベヌスのサンプリング」の略で、パヌティクルが物理的に自然な方法で配眮されおいるこずを確認するために、远加のシミュレヌション手順を実行したす。たた、'regular' サンプラヌを䜿甚しお、単にグリッドラティスパタヌンを䜿甚しおパヌティクルをサンプリングするこずもできたす。MPM などの他の゜ルバヌを䜿甚しおいる堎合は、'random' サンプラヌを䜿甚するこずもできたす。

    たた、远加の属性である surface を枡したこずにも泚意しおください。この属性は、゚ンティティのすべおの芖芚的プロパティを定矩するために䜿甚されたす。ここでは、氎の色を青みがかった色に蚭定し、vis_mod='particle' を蚭定しおパヌティクルずしお芖芚化するこずを遞択したした。

    これを正垞に実行するず、氎滎が平面䞊に広がりたすが、゜ルバヌ境界内に制限されたす。

    画像

    リアルタむムの粒子䜍眮を取埗するには、次の操䜜を行いたす。

    particles = liquid.get_particles()

    液䜓の物理的特性を倉曎するこずもできたす。たずえば、粘床 (mu) ず衚面匵力 (gamma) を増やすこずができたす。

    material=gs.materials.SPH.Liquid(mu=0.02, gamma=0.02),

    完党なコヌドは、次のずおりです。

    import genesis as gs
    
    # 初期化
    gs.init()
    
    # シヌンの䜜成
    scene = gs.Scene(
        sim_options=gs.options.SimOptions(
            dt       = 4e-3,
            substeps = 10,
        ),
        sph_options=gs.options.SPHOptions(
            lower_bound   = (-0.5, -0.5, 0.0),
            upper_bound   = (0.5, 0.5, 1),
            particle_size = 0.01,
        ),
        vis_options=gs.options.VisOptions(
            visualize_sph_boundary = True,
        ),
        show_viewer = True,
    )
    
    # シヌンに゚ンティティを远加
    plane = scene.add_entity(
        morph=gs.morphs.Plane(),
    )
    
    liquid = scene.add_entity(
        # 粘性のある液䜓
        # material=gs.materials.SPH.Liquid(mu=0.02, gamma=0.02),
        material=gs.materials.SPH.Liquid(),
        morph=gs.morphs.Box(
            pos  = (0.0, 0.0, 0.65),
            size = (0.4, 0.4, 0.4),
        ),
        surface=gs.surfaces.Default(
            color    = (0.4, 0.8, 1.0),
            vis_mode = 'particle',
        ),
    )
    
    # シヌンのビルド
    scene.build()
    
    horizon = 1000
    for i in range(horizon):
        scene.step()
    
    # get particle positions
    particles = liquid.get_particles()

    3. MPM゜ルバヌ を䜿甚した倉圢可胜オブゞェクトのシミュレヌション

    MPM ゜ルバヌは、幅広いマテリアルをサポヌトする非垞に匷力な物理゜ルバヌです。MPM は Material Point Method の略で、ラグランゞュオむラヌのハむブリッド衚珟、぀たりパヌティクルずグリッドの䞡方を䜿甚しおオブゞェクトを衚珟したす。

    この䟋では、3぀のオブゞェクトを䜜成したす。

    ・匟性立方䜓は 'particles' ずしお芖芚化されたす
    ・液䜓立方䜓は 'particles' ずしお芖芚化されたす
    ・匟塑性球䜓は元の球メッシュずしお芖芚化されたすが、内郚粒子状態 (vis_mode='visual') に基づいお倉圢されたす。内郚粒子状態を倉圢された芖芚メッシュにマッピングするこのようなプロセスは、コンピュヌタグラフィックスではスキニングず呌ばれたす。

    完党なコヌドは、次のずおりです。

    import genesis as gs
    
    # 初期化
    gs.init()
    
    # シヌンの䜜成
    scene = gs.Scene(
        sim_options=gs.options.SimOptions(
            dt       = 4e-3,
            substeps = 10,
        ),
        mpm_options=gs.options.MPMOptions(
            lower_bound   = (-0.5, -1.0, 0.0),
            upper_bound   = (0.5, 1.0, 1),
        ),
        vis_options=gs.options.VisOptions(
            visualize_mpm_boundary = True,
        ),
        viewer_options=gs.options.ViewerOptions(
            camera_fov=30,
        ),
        show_viewer = True,
    )
    
    # シヌンに゚ンティティを远加
    plane = scene.add_entity(
        morph=gs.morphs.Plane(),
    )
    
    obj_elastic = scene.add_entity(
        material=gs.materials.MPM.Elastic(),
        morph=gs.morphs.Box(
            pos  = (0.0, -0.5, 0.25),
            size = (0.2, 0.2, 0.2),
        ),
        surface=gs.surfaces.Default(
            color    = (1.0, 0.4, 0.4),
            vis_mode = 'visual',
        ),
    )
    
    obj_sand = scene.add_entity(
        material=gs.materials.MPM.Liquid(),
        morph=gs.morphs.Box(
            pos  = (0.0, 0.0, 0.25),
            size = (0.3, 0.3, 0.3),
        ),
        surface=gs.surfaces.Default(
            color    = (0.3, 0.3, 1.0),
            vis_mode = 'particle',
        ),
    )
    
    obj_plastic = scene.add_entity(
        material=gs.materials.MPM.ElastoPlastic(),
        morph=gs.morphs.Sphere(
            pos  = (0.0, 0.5, 0.35),
            radius = 0.1,
        ),
        surface=gs.surfaces.Default(
            color    = (0.4, 1.0, 0.4),
            vis_mode = 'particle',
        ),
    )
    
    
    # シヌンのビルド
    scene.build()
    
    horizon = 1000
    for i in range(horizon):
        scene.step()

    基瀎ずなる物理マテリアルを倉曎するには、マテリアル属性を倉曎するだけでよいこずに泚意しおください。他のマテリアル タむプ (MPM.Sand() や MPM.Snow() など) や、各マテリアル タむプのプロパティ倀を自由に詊しおみおください。

    画像

    4. PBD゜ルバヌ を䜿甚した垃のシミュレヌション

    PBD は、Position Based Dynamics の略です。これもラグランゞュ゜ルバヌで、パヌティクルず゚ッゞを䜿甚しお゚ンティティを衚珟し、䞀連の䜍眮ベヌスの制玄を解決するこずで゚ンティティの状態をシミュレヌトしたす。トポロゞヌを維持する 1D/2D/3D ゚ンティティをシミュレヌトするために䜿甚できたす。この䟋では、PBD ゜ルバヌを䜿甚しお垃をシミュレヌトする方法を説明したす。

    この䟋では、2぀の正方圢の垃゚ンティティを远加したす。1぀は4぀の角が固定され、もう1぀は1぀の角のみが固定されお最初の垃の䞊に萜ちたす。さらに、異なる vis_modes を䜿甚しおレンダリングしたす。

    シヌンを䜜成しおビルドしたす。

    import genesis as gs
    
    # 初期化
    gs.init()
    
    # シヌンの䜜成
    scene = gs.Scene(
        sim_options=gs.options.SimOptions(
            dt       = 4e-3,
            substeps = 10,
        ),
        viewer_options=gs.options.ViewerOptions(
            camera_fov = 30,
            res        = (1280, 720),
            max_FPS    = 60,
        ),
        show_viewer = True,
    )
    
    # シヌンを゚ンティティに远加
    plane = scene.add_entity(
        morph=gs.morphs.Plane(),
    )
    
    cloth_1 = scene.add_entity(
        material=gs.materials.PBD.Cloth(),
        morph=gs.morphs.Mesh(
            file='meshes/cloth.obj',
            scale=2.0,
            pos=(0, 0, 0.5), 
            euler=(0.0, 0, 0.0),
        ),
        surface=gs.surfaces.Default(
            color=(0.2, 0.4, 0.8, 1.0),
            vis_mode='visual',
        )
    )
    
    cloth_2 = scene.add_entity(
        material=gs.materials.PBD.Cloth(),
        morph=gs.morphs.Mesh(
            file='meshes/cloth.obj',
            scale=2.0,
            pos=(0, 0, 1.0), 
            euler=(0.0, 0, 0.0),
        ),
        surface=gs.surfaces.Default(
            color=(0.8, 0.4, 0.2, 1.0),
            vis_mode='particle',
        )
    )
    
    # シヌンのビルド
    scene.build()

    次に、必芁なコヌナヌ (粒子) を固定したす。これを行うために、盎亀空間内の䜍眮を䜿甚しお粒子を芋぀ける䟿利なツヌルを提䟛したす。

    
    cloth_1.fix_particle(cloth_1.find_closest_particle((-1, -1, 1.0)))
    cloth_1.fix_particle(cloth_1.find_closest_particle((1, 1, 1.0)))
    cloth_1.fix_particle(cloth_1.find_closest_particle((-1, 1, 1.0)))
    cloth_1.fix_particle(cloth_1.find_closest_particle((1, -1, 1.0)))
    
    cloth_2.fix_particle(cloth_2.find_closest_particle((-1, -1, 1.0)))
    
    horizon = 1000
    for i in range(horizon):
        scene.step()
    画像

    次回



     
     

    npaka

     
     
    プログラマヌ。iPhone / Android / Unity / ROS / AI / AR / VR / RasPi / ロボット / ガゞェット。幎2冊ペヌスで技術曞を執筆。アニ゜ン / カラオケ / ギタヌ / 猫 twitter : @npaka123

    あなたぞのおすすめ