.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "_gallery/feature_demo/morph_targets.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr__gallery_feature_demo_morph_targets.py: Morph Targets ============= This example demonstrates how to use morph targets to animate a mesh. .. GENERATED FROM PYTHON SOURCE LINES 7-92 .. image-sg:: /_gallery/feature_demo/images/sphx_glr_morph_targets_001.webp :alt: morph targets :srcset: /_gallery/feature_demo/images/sphx_glr_morph_targets_001.webp :class: sphx-glr-single-img .. code-block:: Python import math import time import numpy as np import pygfx as gfx import pylinalg as la from rendercanvas.auto import RenderCanvas, loop def create_geometry(): geometry = gfx.box_geometry(2, 2, 2, 32, 32, 32) # the original positions of the cube's vertices positions = geometry.positions # for the first morph target we'll move the cube's vertices onto the surface of a sphere sphere_positions = np.zeros_like(positions.data) # for the second morph target, we'll twist the cubes vertices twist_positions = np.zeros_like(positions.data) for i in range(positions.nitems): x, y, z = positions.data[i] # sphere sphere_positions[i] = ( x * math.sqrt(1 - (y**2 / 2) - (z**2 / 2) + (y**2 * z**2 / 3)), y * math.sqrt(1 - (z**2 / 2) - (x**2 / 2) + (z**2 * x**2 / 3)), z * math.sqrt(1 - (x**2 / 2) - (y**2 / 2) + (x**2 * y**2 / 3)), ) # twist # stretch along the x-axis so we can see the twist better twist_positions[i] = la.vec_transform_quat( (2 * x, y, z), la.quat_from_axis_angle((1, 0, 0), math.pi * x / 2) ) geometry.morph_positions = [] # add the spherical positions as the first morph target geometry.morph_positions.append(sphere_positions) # add the twist positions as the second morph target geometry.morph_positions.append(twist_positions) return geometry canvas = RenderCanvas(size=(640, 480), max_fps=60, title="Morph Targets") renderer = gfx.WgpuRenderer(canvas) camera = gfx.PerspectiveCamera(45, 640 / 480, depth_range=(0.1, 100)) scene = gfx.Scene() geometry = create_geometry() material = gfx.MeshNormalMaterial() mesh = gfx.Mesh(geometry, material) scene.add(mesh) camera.show_object(mesh, scale=2.5) controller = gfx.OrbitController(camera, register_events=renderer) gfx.OrbitController(camera, register_events=renderer) def animate(): t = time.time() mesh.morph_target_influences = [ 0.5 + 0.5 * math.sin(t), 0.5 + 0.5 * math.cos(t + 1), ] renderer.render(scene, camera) canvas.request_draw() if __name__ == "__main__": canvas.request_draw(animate) loop.run() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 10.894 seconds) .. _sphx_glr_download__gallery_feature_demo_morph_targets.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: morph_targets.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: morph_targets.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: morph_targets.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_ .. only:: html Interactive example ------------------- Try this example in your browser using Pyodide. Might not work with all examples and all devices. Check the output and your browser's console for details. .. raw:: html