### Install live2d-py from local wheel file Source: https://github.com/easylive2d/live2d-py/blob/main/README.en.md Install the live2d-py library by providing the path to a downloaded .whl file. This is the recommended installation method. ```shell pip install live2d_py-0.X.X-cpXXX-cpXXX-win32.whl ``` -------------------------------- ### Build and Install live2d-py Source: https://github.com/easylive2d/live2d-py/blob/main/CONTRIBUTING.en.md Use these commands to build the project from source, download the SDK, or create a wheel package. Ensure you have the necessary build tools installed. ```bash pip install . ``` ```bash python setup.py download ``` ```bash python setup.py bdist_wheel ``` -------------------------------- ### Install Dependencies with Pip Source: https://github.com/easylive2d/live2d-py/blob/main/examples/README.en.md Use this command to install project dependencies from a requirements file. Ensure you have Python 3.7+ and the live2d-python package installed. ```bash pip install -r requirements.txt ``` -------------------------------- ### Hit Detection Setup Source: https://context7.com/easylive2d/live2d-py/llms.txt Prepare for hit detection by initializing Pygame and the Live2D SDK. This is a prerequisite for implementing click interactions with model parts. ```python import pygame import live2d.v3 as live2d ``` -------------------------------- ### Install live2d-py from PyPI Source: https://github.com/easylive2d/live2d-py/blob/main/README.en.md Install the live2d-py library directly from the Python Package Index (PyPI) using pip. ```shell pip install live2d-py ``` -------------------------------- ### Initialize WavHandler and lipSyncN Source: https://github.com/easylive2d/live2d-py/wiki/口型同步 Create a WavHandler object and set the lipSyncN multiplier for mouth synchronization. This is typically done at the beginning of your application setup. ```python from live2d.utils.lipsync import WavHandler wavHandler = WavHandler() lipSyncN = 3 ``` -------------------------------- ### Start Audio Playback and Lip Sync Source: https://github.com/easylive2d/live2d-py/wiki/口型同步 This callback function is triggered when a motion starts. It loads and plays an audio file using Pygame's mixer and initializes the WavHandler for lip synchronization. ```python def start_callback(group, no): # 播放音频 pygame.mixer.music.load("audio1.wav") pygame.mixer.music.play() # 处理口型同步 wavHandler.Start("audio1.wav") ``` -------------------------------- ### Find Qt6 Components Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Locates and includes necessary Qt6 components for the project. Ensure Qt6 is installed and discoverable by CMake. ```cmake find_package(Qt6 COMPONENTS Core Widgets Gui OpenGLWidgets LinguistTools REQUIRED) ``` -------------------------------- ### Integrate Live2D Model with Qt Application Source: https://context7.com/easylive2d/live2d-py/llms.txt Use this snippet to display Live2D models in a transparent, frameless Qt window. Ensure Live2D models are loaded and initialized before starting the application loop. ```python import os from PySide6.QtCore import Qt from PySide6.QtOpenGLWidgets import QOpenGLWidget from PySide6.QtWidgets import QApplication from PySide6.QtGui import QGuiApplication import live2d.v3 as live2d class Live2DWidget(QOpenGLWidget): def __init__(self): super().__init__() # Transparent, frameless window self.setWindowFlags(Qt.WindowType.FramelessWindowHint) self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground, True) self.resize(400, 500) self.model = None self.systemScale = QGuiApplication.primaryScreen().devicePixelRatio() def initializeGL(self): live2d.glInit() self.model = live2d.LAppModel() self.model.LoadModelJson("Resources/v3/Haru/Haru.model3.json") self.startTimer(int(1000 / 60)) # 60 FPS def resizeGL(self, w, h): if self.model: self.model.Resize(w, h) def paintGL(self): live2d.clearBuffer() self.model.Update() self.model.Draw() def timerEvent(self, event): self.update() # Trigger repaint if __name__ == "__main__": import sys live2d.init() app = QApplication(sys.argv) widget = Live2DWidget() widget.show() app.exec() live2d.dispose() ``` -------------------------------- ### Motion Playback with Callbacks Source: https://context7.com/easylive2d/live2d-py/llms.txt Play motions defined in the model's configuration file. Motions can be triggered by group name and index, or randomly. Callback functions notify when motions start and finish. ```python import live2d.v3 as live2d # Callback functions for motion events def on_motion_start(group: str, motion_index: int): print(f"Started motion: {group}_{motion_index}") def on_motion_finish(): print("Motion finished") # After loading model... # Play a specific motion by group and index # Priority levels: NONE=0, IDLE=1, NORMAL=2, FORCE=3 model.StartMotion( group="TapBody", # Motion group name no=0, # Motion index within group priority=live2d.MotionPriority.FORCE, onStartMotionHandler=on_motion_start, onFinishMotionHandler=on_motion_finish ) # Or play a random motion from a group model.StartRandomMotion( group="Idle", priority=3, onFinishMotionHandler=on_motion_finish ) # Check if current motion has finished if model.IsMotionFinished(): print("Ready for next motion") # Stop all currently playing motions model.StopAllMotions() # Get available motion groups and counts motion_groups = model.GetMotionGroups() # Returns dict: {"Idle": 2, "TapBody": 3, ...} ``` -------------------------------- ### Handle Mouse Clicks on Live2D Model Parts Source: https://context7.com/easylive2d/live2d-py/llms.txt Detect mouse clicks on specific model parts like 'Head' or 'Body' and trigger actions. Also shows how to get all parts at a click position and highlight the top one. ```python part_ids = model.GetPartIds() while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEBUTTONDOWN: x, y = pygame.mouse.get_pos() # Check predefined hit areas (defined in model3.json) if model.HitTest("Head", x, y): print("Head clicked!") model.SetRandomExpression() elif model.HitTest("Body", x, y): print("Body clicked!") model.StartRandomMotion("TapBody", priority=3) # Or get all parts at click position hit_parts = model.HitPart(x, y, topOnly=False) if hit_parts: print(f"Clicked parts: {hit_parts}") # Highlight the top clicked part top_part = hit_parts[0] part_idx = part_ids.index(top_part) model.SetPartOpacity(part_idx, 0.5) live2d.clearBuffer() model.Update() model.Draw() pygame.display.flip() ``` -------------------------------- ### Include Patch Script Source: https://github.com/easylive2d/live2d-py/blob/main/Live2D/Main/CMakeLists.txt Includes and executes a CMake script named 'patch_1.cmake' during the configuration phase. This is used for immediate file modifications or setup tasks. ```cmake include(${CMAKE_CURRENT_SOURCE_DIR}/patch_1.cmake) ``` -------------------------------- ### Get Current Frame Parameter Value Source: https://github.com/easylive2d/live2d-py/wiki/参数控制 Retrieve the value of a specific parameter at the current frame. The parameter is identified by its index. ```python val = model.GetParameterValue(0) ``` -------------------------------- ### Get Model Information Source: https://github.com/easylive2d/live2d-py/wiki/以更细粒度控制-Live2D-模型(编写中) Retrieve various details about the loaded Live2D model, such as parameter IDs, values, motion data, drawable IDs, and canvas dimensions. ```python def GetParameterIds(self) -> list[str]: ... def GetParameterValue(self, index: int) -> float: ... def GetParameterMaximumValue(self, index: int) -> float: ... def GetParameterMinimumValue(self, index: int) -> float: ... def GetParameterDefaultValue(self, index: int) -> float: ... def GetMvp(self) -> list[float]: ... def GetMotions(self) -> dict[str, list[dict[str, str]]]: ... def GetPartIds(self) -> list[str]: ... def GetDrawableIds(self) -> list[str]: ... def GetExpressions(self) -> list[str, str]: ... def GetCanvasSize(self) -> tuple[float, float]: ... def GetCanvasSizePixel(self) -> tuple[float, float]: ... def GetPixelsPerUnit(self) -> float: ... ``` -------------------------------- ### Set Custom Model Parameter Source: https://github.com/easylive2d/live2d-py/wiki/参数控制 Set a custom model parameter, such as a watermark control. The parameter ID must be identified from the model's configuration files (e.g., `XXX.cdi3.json`). This example assumes `Param261` controls a watermark, where `0` shows it and `1` hides it. ```python # 根据模型发布者或者模型 XXX.cdi3.json 中可查找到水印对应的参数 id # 假设查找到的模型参数 id 为 Param261,假设值为 0 表示显示水印,值为 1 表示消失 model.SetParameterValue("Param261", 1, 1) ``` -------------------------------- ### Simple Facerig Demo Source: https://github.com/easylive2d/live2d-py/blob/main/README.en.md This demo showcases facial binding using MediaPipe. The source code is available at examples/main_facial_bind.py. ```python # Source code: [main_facial_bind_mediapipe.py](./examples/main_facial_bind.py) ``` -------------------------------- ### Model Initialization and Loading Source: https://github.com/easylive2d/live2d-py/wiki/以更细粒度控制-Live2D-模型(编写中) Before creating a Model instance, the live2d library must be initialized. Then, a Model instance can be created and a model3.json file can be loaded to set up the model, including its associated expressions, poses, animations, and moc3 data. ```APIDOC ## Initialization Initialize the live2d library before creating any model instances. ```python from live2d.v3 import init init() ``` ## Model Loading Create a `Model` instance and load the `model3.json` file. This action automatically loads associated assets like `exp3.json`, `pose3.json`, `motion3.json`, and `moc3`. ### Method ```python model = Model() model.LoadModelJson("path/to/model3.json") ``` **Note**: File paths within `model3.json` are relative to the directory containing `model3.json`. ``` -------------------------------- ### Model Opacity Control Demo Source: https://github.com/easylive2d/live2d-py/blob/main/README.en.md This demo illustrates how to control the opacity of Live2D models. The source code is located at examples/main_pyqt5_canvas_opacity.py. ```python # Source Code: [main_pyqt5_canvas_opacity.py](./examples/main_pyqt5_canvas_opacity.py) ``` -------------------------------- ### Windows Deployment with windeployqt6 Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Configures a post-build custom command on Windows to deploy necessary Qt libraries using windeployqt6, copy the icon, and shaders. ```cmake if(WIN32) set(MARKER $,${PROJECT_SOURCE_DIR}/x64/Debug/.deployed,${PROJECT_SOURCE_DIR}/x64/Release/.deployed>) # 获取 windeployqt6 工具的路径 get_target_property(_qmake_executable Qt6::qmake IMPORTED_LOCATION) get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) find_program(WINDEPLOYQT_EXECUTABLE windeployqt6 HINTS "${_qt_bin_dir}") add_custom_command( TARGET Live2DViewer POST_BUILD COMMAND if not exist ${MARKER} (${WINDEPLOYQT_EXECUTABLE} $ && echo done. > ${MARKER}) else (echo deployed) COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/moeroid.ico $/moeroid.ico COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/../Live2D/Framework/src/Rendering/OpenGL/Shaders/Standard $/FrameworkShaders ) else() # Linux deployment - just copy the icon add_custom_command( TARGET Live2DViewer POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/moeroid.ico $/moeroid.ico COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/../Live2D/Framework/src/Rendering/OpenGL/Shaders/Standard $/FrameworkShaders ) endif() ``` -------------------------------- ### Model Transforming, Lipsync, and Click Test Demo Source: https://github.com/easylive2d/live2d-py/blob/main/README.en.md A comprehensive demo featuring model transformations, lipsyncing from a WAV file, and click interaction tests. The source code is available at examples/main_pygame.py. ```python # Source code: [main_pygame.py](./examples/main_pygame.py) ``` -------------------------------- ### Link Libraries Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Links the executable against required Qt6 modules and the Live2D::Main library. ```cmake target_link_libraries(Live2DViewer PRIVATE Qt6::Core Qt6::Widgets Qt6::Gui Qt6::OpenGLWidgets Live2D::Main ) ``` -------------------------------- ### Copy Icon File Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Copies the application icon file to the build directory. ```cmake file(COPY moeroid.ico DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) ``` -------------------------------- ### Load Live2D Model Source: https://github.com/easylive2d/live2d-py/wiki/以更细粒度控制-Live2D-模型(编写中) Create a Model instance and load its configuration and assets using the `LoadModelJson` method. Ensure the path points to your model's `model3.json` file. ```python model = Model() model.LoadModelJson("path/to/model3.json") ``` -------------------------------- ### Set Include Directories Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Specifies directories where header files can be found, including the current source directory and Qt include paths. ```cmake target_include_directories(Live2DViewer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${QTINC} ) ``` -------------------------------- ### Initialize Live2D Source: https://github.com/easylive2d/live2d-py/wiki/以更细粒度控制-Live2D-模型(编写中) Initialize the Live2D environment before creating any Model instances. This is a prerequisite for using the library. ```python from live2d.v3 import init, Model init() ``` -------------------------------- ### Main Vertex Shader Source: https://github.com/easylive2d/live2d-py/blob/main/docs/LIVE2D_V2_RENDERER.md Applies MVP matrix transformations to vertices, passes clip-space positions for masking, and passes UV coordinates with Y-axis flipping. ```glsl attribute vec2 a_position; attribute vec2 a_texCoord; varying vec2 v_texCoord; varying vec4 v_clipPos; uniform mat4 u_mvpMatrix; void main() { gl_Position = u_mvpMatrix * vec4(a_position, 0.0, 1.0); v_clipPos = gl_Position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y; // 翻转 Y 轴 } ``` -------------------------------- ### Initialize and Cleanup Live2D Framework Source: https://context7.com/easylive2d/live2d-py/llms.txt Initialize the Live2D framework before loading models and clean up resources when done. The glInit() function must be called after an OpenGL context is established. ```python import live2d.v3 as live2d # For Cubism 3.0+ models # import live2d.v2 as live2d # For Cubism 2.1 and earlier # Initialize Live2D framework (call once at startup) live2d.init() # After creating an OpenGL context (window), initialize GL functions # This must be called AFTER pygame.display.set_mode() or equivalent live2d.glInit() # ... your application code ... # Clean up when done (before closing the application) live2d.dispose() ``` -------------------------------- ### Live2D Rendering with Background Image Demo Source: https://github.com/easylive2d/live2d-py/blob/main/README.en.md This demo shows how to render Live2D models with a background image. The source code can be found at examples/main_pygame_background.py. ```python # Source code: [main_pygame_background.py](./examples/main_pygame_background.py) ``` -------------------------------- ### Multi-live2d Model Rendering Demo Source: https://github.com/easylive2d/live2d-py/blob/main/README.en.md Demonstrates rendering multiple Live2D models simultaneously. The source code is located at examples/main_pygame_three_model.py. ```python # Source code: [main_pygame_three_model.py](./examples/main_pygame_three_model.py) ``` -------------------------------- ### Define Executable Target Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Defines the main executable target 'Live2DViewer' and lists all its source files, UI files, and header files. ```cmake add_executable(Live2DViewer Main.cpp scene/Live2DScene.hpp scene/Live2DScene.cpp MainWindow.ui MainWindow.hpp MainWindow.cpp Live2DView.ui Live2DView.hpp Live2DView.cpp ) ``` -------------------------------- ### Conditional Build for Viewer or Wrapper Source: https://github.com/easylive2d/live2d-py/blob/main/CMakeLists.txt Includes Live2D CMake modules and conditionally includes either Live2DViewer.cmake or Wrapper.cmake based on the VIEWER variable. ```cmake include(Live2D/cmake/Live2D.cmake) # set(VIEWER 1) if(DEFINED VIEWER) message("Build for Viewer") include(cmake/Live2DViewer.cmake) else() message("Build for Wrapper") include(cmake/Wrapper.cmake) endif() ``` -------------------------------- ### Create Live2D Renderer Source: https://github.com/easylive2d/live2d-py/wiki/以更细粒度控制-Live2D-模型(编写中) After loading the model, create an internal renderer using `Model.CreateRenderer`. This must be called after an OpenGL context is active. ```python makeContextCurrent() # 创建 OpenGL 上下文 model.CreateRenderer(2) ``` -------------------------------- ### Set CMake Build Options Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Configures automatic handling of Qt's meta-object compiler (moc), UI files, and resource files. ```cmake set(CMAKE_PREFIX_PATH "/home/thyne/Qt/6.9.1/gcc_64/lib/cmake/Qt6/") set(CMAKE_AUTOMOC ON) # 自动处理 Q_OBJECT 宏的元对象编译(moc) set(CMAKE_AUTOUIC ON) # 自动编译 UI 文件(.ui → .h) set(CMAKE_AUTORCC ON) # 自动编译资源文件(.qrc → .cpp) ``` -------------------------------- ### Configure Live2D Framework CMake Project Source: https://github.com/easylive2d/live2d-py/blob/main/Live2D/Framework/CMakeLists.txt Sets up the CMake build system for the Live2D Framework, defining the library name, type, and source directories. It also configures include paths and compile definitions. ```cmake cmake_minimum_required(VERSION 3.10) set(LIB_NAME Framework) # Force static library. add_library(${LIB_NAME} STATIC) add_subdirectory(src) # Add include path. target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src PRIVATE ${RENDER_INCLUDE_PATH} ) # Deprecated functions # The following expressions are written for compatibility # and will be removed in a future release. # Add core include. target_include_directories(${LIB_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../Core/include ) # Add definitions. target_compile_definitions(${LIB_NAME} PRIVATE ${FRAMEWORK_DEFINITIOINS} ) ``` -------------------------------- ### Integrate Live2D CMake Source: https://github.com/easylive2d/live2d-py/blob/main/Live2D/README.md Include the Live2D CMake module and link the Live2D::Main target library to your project. Ensure all required C modules are available. ```cmake include(Live2D/cmake/Live2D.cmake) target_link_libraries( Live2D::Main) ``` -------------------------------- ### Main Fragment Shader Source: https://github.com/easylive2d/live2d-py/blob/main/docs/LIVE2D_V2_RENDERER.md Handles normal rendering and mask rendering. Includes pre-multiplied alpha, multiply blend, and screen blend operations. ```glsl precision mediump float; varying vec2 v_texCoord; varying vec4 v_clipPos; uniform sampler2D s_texture0; uniform vec4 u_channelFlag; uniform vec4 u_baseColor; uniform bool u_maskFlag; uniform vec4 u_screenColor; uniform vec4 u_multiplyColor; void main() { vec4 smpColor; if (u_maskFlag) { // 蒙版渲染模式 float isInside = step(u_baseColor.x, v_clipPos.x / v_clipPos.w) * step(u_baseColor.y, v_clipPos.y / v_clipPos.w) * step(v_clipPos.x / v_clipPos.w, u_baseColor.z) * step(v_clipPos.y / v_clipPos.w, u_baseColor.w); smpColor = u_channelFlag * texture2D(s_texture0, v_texCoord).a * isInside; } else { // 正常渲染模式 smpColor = texture2D(s_texture0, v_texCoord); smpColor.rgb = smpColor.rgb * smpColor.a; // 预乘 Alpha smpColor.rgb = smpColor.rgb * u_multiplyColor.rgb; // 乘法混合 smpColor.rgb = smpColor.rgb + u_screenColor.rgb - (smpColor.rgb * u_screenColor.rgb); // 屏幕混合 smpColor = smpColor * u_baseColor; } gl_FragColor = smpColor; } ``` -------------------------------- ### Iterate and Print All Model Parameters Source: https://github.com/easylive2d/live2d-py/wiki/参数控制 Retrieve and print details for all available parameters in the model. This includes the parameter's ID, type, current value, maximum value, minimum value, and default value. Useful for debugging and understanding model capabilities. ```python # 获取全部可用参数 for i in range(model.GetParameterCount()): param: Parameter = model.GetParameter(i) print(param.id, param.type, param.value, param.max, param.min, param.default) ``` -------------------------------- ### Configure MSVC Compiler and Linker Flags Source: https://github.com/easylive2d/live2d-py/blob/main/CMakeLists.txt Adds debug information flags (/Zi) for release builds and specific warning/library options for MSVC compiler. Includes UTF-8 encoding for the compiler. ```cmake if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi") add_compile_options("/utf-8" "/wd4018" "/wd4244" "/wd4996") add_link_options("/NODEFAULTLIB:LIBCMT") if (CMAKE_CL_64) add_link_options("/BASE:0x800000000") endif() endif() ``` -------------------------------- ### Set Platform-Specific Output Directories Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Configures the output directories for the executable in debug and release modes, specific to Windows. ```cmake if(WIN32) set_target_properties(Live2DViewer PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/x64/Debug RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/x64/Release ) endif() ``` -------------------------------- ### Load and Display Live2D Model with Pygame Source: https://context7.com/easylive2d/live2d-py/llms.txt Load a Live2D model from its JSON configuration file and render it in a Pygame window. The model must be resized to match the display dimensions for proper rendering. ```python import os import pygame import live2d.v3 as live2d def main(): pygame.init() live2d.init() display = (300, 400) pygame.display.set_mode(display, pygame.DOUBLEBUF | pygame.OPENGL) pygame.display.set_caption("Live2D Demo") live2d.glInit() # Create and load model model = live2d.LAppModel() model.LoadModelJson("Resources/v3/Haru/Haru.model3.json") # Resize model to fit window dimensions model.Resize(*display) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # Clear the buffer before drawing live2d.clearBuffer() # Update model state (animations, breathing, blinking, etc.) model.Update() # Render the model model.Draw() pygame.display.flip() live2d.dispose() pygame.quit() if __name__ == "__main__": main() ``` -------------------------------- ### Set Windows-Specific Linker Flags Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Configures linker properties for release builds on Windows, specifying the subsystem and entry point. ```cmake if(WIN32) set_target_properties(Live2DViewer PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup" ) endif() ``` -------------------------------- ### Lip Sync with Audio Source: https://context7.com/easylive2d/live2d-py/llms.txt Synchronize mouth movements with audio using WavHandler. This utility extracts audio amplitude to drive the ParamMouthOpenY parameter. Ensure pygame.mixer is initialized. ```python import pygame import live2d.v3 as live2d from live2d.v3.params import StandardParams from live2d.utils.lipsync import WavHandler pygame.mixer.init() live2d.init() # After loading model... model.SetAutoBreathEnable(False) # Create lip sync handler wav_handler = WavHandler() lip_sync_multiplier = 3 # Adjust for sensitivity # Start audio playback and lip sync audio_path = "path/to/audio.wav" pygame.mixer.music.load(audio_path) pygame.mixer.music.play() wav_handler.Start(audio_path) # In your main loop: while running: # ... event handling ... # Update lip sync if wav_handler.Update(): # Get current audio RMS and apply to mouth parameter rms = wav_handler.GetRms() model.SetParameterValue( StandardParams.ParamMouthOpenY, rms * lip_sync_multiplier ) live2d.clearBuffer() model.Update() model.Draw() pygame.display.flip() ``` -------------------------------- ### Configure Live2D Logging Source: https://context7.com/easylive2d/live2d-py/llms.txt Enable and configure debug logging for Live2D operations to help troubleshoot model loading and rendering issues. Set the log level to DEBUG for maximum detail. ```python import live2d.v3 as live2d # Enable logging live2d.enableLog(True) # Set log level (DEBUG shows most detail) live2d.setLogLevel(live2d.Live2DLogLevels.LV_DEBUG) # Other levels: LV_INFO, LV_WARN, LV_ERROR # Check logging status is_enabled = live2d.isLogEnabled() current_level = live2d.getLogLevel() # Using the log utility from live2d.utils import log log.Debug("Debug message") log.Info("Info message") ``` -------------------------------- ### Add Translations Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Integrates translation files (.ts) into the build process using Qt6's translation tools. ```cmake set(ts_files Translations/moe_zh_CN.ts Translations/moe_en.ts Translations/moe_ja_JP.ts ) qt6_add_translations(Live2DViewer TS_FILES ${ts_files}) ``` -------------------------------- ### Part Opacity and Color Control Source: https://context7.com/easylive2d/live2d-py/llms.txt Adjust the visibility and color tint of individual model parts. Use GetPartIds to retrieve part identifiers. Opacity ranges from 0.0 (invisible) to 1.0 (fully visible). ```python import live2d.v3 as live2d # After loading model... # Get all part IDs part_ids = model.GetPartIds() print(f"Available parts: {part_ids}") # Set opacity of a specific part (0.0 = invisible, 1.0 = fully visible) part_index = part_ids.index("PartHairBack") model.SetPartOpacity(part_index, 0.5) # 50% transparent # Set multiply color (tints the part) # Parameters: partIndex, r, g, b, a (all 0.0-1.0) model.SetPartMultiplyColor(part_index, 0.0, 0.0, 1.0, 1.0) # Blue tint # Set screen color (adds brightness) model.SetPartScreenColor(part_index, 1.0, 0.0, 0.0, 0.5) # Red highlight # Get current colors multiply_color = model.GetPartMultiplyColor(part_index) # Returns (r, g, b, a) screen_color = model.GetPartScreenColor(part_index) ``` -------------------------------- ### Add glad Library in CMake Source: https://github.com/easylive2d/live2d-py/blob/main/Live2D/Glad/CMakeLists.txt Adds the glad C source file as a library. Ensure the source directory is correctly specified. ```cmake add_library(glad ${CMAKE_CURRENT_SOURCE_DIR}/src/glad.c ) ``` -------------------------------- ### Model Rendering Source: https://github.com/easylive2d/live2d-py/wiki/以更细粒度控制-Live2D-模型(编写中) To render a Live2D model, you need to create an internal renderer after loading the model. The drawing process involves clearing the buffer and then calling the model's Draw method within a rendering loop, ensuring an OpenGL context is current. ```APIDOC ## Rendering a Model Rendering requires an OpenGL context and a created renderer. ### Steps 1. **Ensure OpenGL Context**: Make sure an OpenGL context is current. ```python makeContextCurrent() # Assuming this function sets up the context ``` 2. **Create Renderer**: Create the model's internal renderer. ```python model.CreateRenderer(maskBufferCount=2) ``` 3. **Rendering Loop**: Within your application's main loop, clear the buffer and draw the model. ```python while running: live2d.clearBuffer() model.Draw() # Other rendering or application logic ... ``` **Note**: `CreateRenderer` must be called after an OpenGL context is available, and `Draw` must be called after `CreateRenderer`. ``` -------------------------------- ### Physics Simulation Update Source: https://github.com/easylive2d/live2d-py/blob/main/docs/LIVE2D_V2_RENDERER.md Implements a two-mass spring system for physics simulation. Handles time step limitations and calculates forces including gravity, drag, and stiffness. ```python def updatePhysics(self, deltaTime): # 限制最小时间步长 if deltaTime < 0.033: deltaTime = 0.033 # 1. 计算点 1 的运动(受输入参数驱动) invTime = 1.0 / deltaTime p1.vx = (p1.x - p1.lastX) * invTime p1.vy = (p1.y - p1.lastY) * invTime p1.ax = (p1.vx - p1.lastVX) * invTime p1.ay = (p1.vy - p1.lastVY) * invTime # 2. 计算受力 angle = atan2(p2.y - p1.y, p2.x - p1.x) gravity = 9.8 * p2.mass angleRad = DEG_TO_RAD * self.angle # 重力分量 forceGravity = gravity * cos(angle - angleRad) forceX = forceGravity * sin(angle) forceY = forceGravity * cos(angle) # 阻力(空气阻力) forceDragX = -p1.fx * sin(angle) * sin(angle) forceDragY = -p1.fy * sin(angle) * cos(angle) # 弹簧力 forceStiffnessX = -p2.vx * stiffness forceStiffnessY = -p2.vy * stiffness # 3. 应用力到点 2 p2.fx = forceX + forceDragX + forceStiffnessX p2.fy = forceY + forceDragY + forceStiffnessY # 4. 更新速度和位置 p2.vx += p2.ax * deltaTime p2.vy += p2.ay * deltaTime p2.x += p2.vx * deltaTime p2.y += p2.vy * deltaTime # 5. 保持固定距离 currentDistance = sqrt((p2.x - p1.x)^2 + (p2.y - p1.y)^2) ratio = self.length / currentDistance p2.x = p1.x + (p2.x - p1.x) * ratio p2.y = p1.y + (p2.y - p1.y) * ratio ``` -------------------------------- ### Compile GLSL Shaders to SPIR-V Source: https://github.com/easylive2d/live2d-py/blob/main/Live2D/Framework/src/Rendering/Vulkan/Shaders/CMakeLists.txt This script iterates through shader files, compiles them to SPIR-V format using glslc, and sets up custom commands for compilation. It handles platform-specific commands for Windows and Unix-like systems. ```cmake file(GLOB shader_files src/*) # Shader compilation foreach(shader ${shader_files}) get_filename_component(file_name ${shader} NAME) if(file_name MATCHES "common.glsl") continue() endif() get_filename_component(full_path ${shader} ABSOLUTE) set(output_dir ${CMAKE_CURRENT_BINARY_DIR}/compiledShaders) string(REGEX REPLACE \.frag|\.vert "" output_file ${file_name}) set(output_file ${output_dir}/${output_file}.spv) set(compiled_shaders_framework ${compiled_shaders_framework} ${output_file}) set(compiled_shaders_framework ${compiled_shaders_framework} PARENT_SCOPE) set_source_files_properties(${shader} PROPERTIES HEADER_FILE_ONLY TRUE) if(WIN32) add_custom_command( OUTPUT ${output_file} COMMAND ${CMAKE_COMMAND} -E make_directory ${output_dir} COMMAND $ENV{VK_SDK_PATH}/Bin/glslc.exe ${full_path} -o ${output_file} DEPENDS ${full_path} ) endif() if(UNIX AND NOT APPLE) add_custom_command( OUTPUT ${output_file} COMMAND ${CMAKE_COMMAND} -E make_directory ${output_dir} COMMAND glslc ${full_path} -o ${output_file} DEPENDS ${full_path} ) endif() endforeach() source_group("shaders" FILES ${shader_files}) add_custom_target( FrameworkShaders ALL DEPENDS ${compiled_shaders_framework} SOURCES ${shader_files} ) ``` -------------------------------- ### Set Platform-Specific Compile Definitions Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Defines preprocessor macros based on the target operating system (Windows or Linux). ```cmake if(WIN32) target_compile_definitions(Live2DViewer PRIVATE CSM_TARGET_WIN_GL UNICODE _UNICODE ) else() target_compile_definitions(Live2DViewer PRIVATE CSM_TARGET_LINUX_GL ) endif() ``` -------------------------------- ### Set Standard Parameter Using Enum Source: https://github.com/easylive2d/live2d-py/wiki/参数控制 Set a standard model parameter using predefined constants from `live2d.vX.params.StandardParams`. This improves code readability and reduces the risk of typos when referencing parameter IDs. ```python # v3 from live2d.v3.params import StandardParams # v2 # from live2d.v3.params import StandardParams model.SetParameterValue(StandardParams.ParamMouthOpenY, 1.0, 1.0) ``` -------------------------------- ### Set glad Include Directories in CMake Source: https://github.com/easylive2d/live2d-py/blob/main/Live2D/Glad/CMakeLists.txt Configures the public include directories for the glad library. This allows headers to be found during the build process. ```cmake target_include_directories(glad PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/ ) ``` -------------------------------- ### Add Windows-Specific Resource File Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Conditionally adds a Windows resource file (logo.rc) only when building on a Windows platform. ```cmake if(WIN32) target_sources(Live2DViewer PRIVATE logo.rc) endif() ``` -------------------------------- ### Live2D Standard Parameters Reference Source: https://context7.com/easylive2d/live2d-py/llms.txt Access constants for common Live2D parameters like head rotation, eye and mouth movements, and body/hair physics. These parameters are used to control model expressions and animations. ```python from live2d.v3.params import StandardParams # Head/Face rotation StandardParams.ParamAngleX # Head turn left/right (-30 to 30) StandardParams.ParamAngleY # Head tilt up/down (-30 to 30) StandardParams.ParamAngleZ # Head rotate (-30 to 30) # Eyes StandardParams.ParamEyeLOpen # Left eye openness (0=closed, 1=open) StandardParams.ParamEyeROpen # Right eye openness StandardParams.ParamEyeLSmile # Left eye smile StandardParams.ParamEyeRSmile # Right eye smile StandardParams.ParamEyeBallX # Eye gaze horizontal (-1 to 1) StandardParams.ParamEyeBallY # Eye gaze vertical (-1 to 1) # Eyebrows StandardParams.ParamBrowLY # Left eyebrow position StandardParams.ParamBrowRY # Right eyebrow position StandardParams.ParamBrowLAngle # Left eyebrow angle StandardParams.ParamBrowRAngle # Right eyebrow angle # Mouth StandardParams.ParamMouthOpenY # Mouth openness (0=closed, 1=open) StandardParams.ParamMouthForm # Mouth shape (-1=frown, 1=smile) # Body StandardParams.ParamBodyAngleX # Body lean left/right StandardParams.ParamBodyAngleY # Body lean forward/back StandardParams.ParamBodyAngleZ # Body rotation StandardParams.ParamBreath # Breathing parameter # Arms/Hands StandardParams.ParamArmLA # Left arm position A StandardParams.ParamArmRA # Right arm position A StandardParams.ParamHandL # Left hand StandardParams.ParamHandR # Right hand # Hair physics StandardParams.ParamHairFront # Front hair movement StandardParams.ParamHairSide # Side hair movement StandardParams.ParamHairBack # Back hair movement ``` -------------------------------- ### Enable Mouse Tracking and Eye Gaze Source: https://context7.com/easylive2d/live2d-py/llms.txt Enable the model to follow the mouse cursor by using the Drag() method. This creates natural eye tracking and head turning effects. ```python import pygame import live2d.v3 as live2d # After initializing model... running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEMOTION: # Pass mouse coordinates to enable gaze tracking x, y = pygame.mouse.get_pos() model.Drag(x, y) live2d.clearBuffer() model.Update() model.Draw() pygame.display.flip() ``` -------------------------------- ### Render Live2D Model Source: https://github.com/easylive2d/live2d-py/wiki/以更细粒度控制-Live2D-模型(编写中) Within the rendering loop, clear the buffer and call `model.Draw()` to render the Live2D model. Ensure `CreateRenderer` has been called previously. ```python # 渲染循环 while running: live2d.clearBuffer() model.Draw() ... ``` -------------------------------- ### Update Live2D Model with Audio Loudness Source: https://github.com/easylive2d/live2d-py/wiki/口型同步 In the main update loop, after updating the Live2D model but before drawing, check if WavHandler has new audio data. If available, update the 'ParamMouthOpenY' parameter using the audio's RMS value multiplied by lipSyncN. ```python live2d.clearBuffer() model.Update() # 在 Update 之后,Draw 之前调用 if wavHandler.Update(): # 获取 wav 下一帧片段的响度(Rms),如果没有下一帧片段则为False(音频已播放完毕) model.SetParameterValue("ParamMouthOpenY", wavHandler.GetRms() * lipSyncN) ``` -------------------------------- ### Multi-Model Rendering with Live2D v2 and v3 Source: https://context7.com/easylive2d/live2d-py/llms.txt Load and render multiple Live2D models (v2 and v3) simultaneously in the same Pygame application. Models can be positioned and scaled independently. ```python import os import pygame import live2d.v3 as l2d_v3 import live2d.v2 as l2d_v2 def main(): pygame.init() l2d_v3.init() l2d_v2.init() display = (800, 500) pygame.display.set_mode(display, pygame.DOUBLEBUF | pygame.OPENGL) l2d_v3.glInit() l2d_v2.glInit() # Create multiple models model_v2 = l2d_v2.LAppModel() model_v3_1 = l2d_v3.LAppModel() model_v3_2 = l2d_v3.LAppModel() # Load different model formats model_v3_1.LoadModelJson("Resources/v3/llny/llny.model3.json") model_v3_2.LoadModelJson("Resources/v3/Haru/Haru.model3.json") model_v2.LoadModelJson("Resources/v2/kasumi2/kasumi2.model.json") # Resize all models model_v3_1.Resize(*display) model_v3_2.Resize(*display) model_v2.Resize(*display) # Position models side by side model_v3_1.SetOffset(-0.5, 0.0) # Left model_v2.SetOffset(0.5, 0.3) # Right model_v2.SetScale(0.7) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEMOTION: x, y = pygame.mouse.get_pos() # All models follow mouse model_v3_1.Drag(x, y) model_v3_2.Drag(x, y) model_v2.Drag(x, y) # Clear buffer once l2d_v3.clearBuffer() # Draw models in order (back to front) model_v3_2.Update() model_v3_2.Draw() model_v3_1.Update() model_v3_1.Draw() model_v2.Update() model_v2.Draw() pygame.display.flip() l2d_v3.dispose() l2d_v2.dispose() pygame.quit() if __name__ == "__main__": main() ``` -------------------------------- ### Accessing Model Information Source: https://github.com/easylive2d/live2d-py/wiki/以更细粒度控制-Live2D-模型(编写中) After loading a model, you can retrieve various pieces of information about it, such as parameter IDs and values, motion data, drawable IDs, expression lists, and canvas dimensions. ```APIDOC ## Get Model Information These methods allow you to query details about the loaded model. ### Methods - `GetParameterIds() -> list[str]` - `GetParameterValue(index: int) -> float` - `GetParameterMaximumValue(index: int) -> float` - `GetParameterMinimumValue(index: int) -> float` - `GetParameterDefaultValue(index: int) -> float` - `GetMvp() -> list[float]` - `GetMotions() -> dict[str, list[dict[str, str]]]` - `GetPartIds() -> list[str]` - `GetDrawableIds() -> list[str]` - `GetExpressions() -> list[str, str]` - `GetCanvasSize() -> tuple[float, float]` - `GetCanvasSizePixel() -> tuple[float, float]` - `GetPixelsPerUnit() -> float` ``` -------------------------------- ### Set Platform-Specific Compiler Options Source: https://github.com/easylive2d/live2d-py/blob/main/Live2DViewer/CMakeLists.txt Applies different compiler flags based on the compiler being used (MSVC, GNU, or Clang). ```cmake if(MSVC) target_compile_options(Live2DViewer PRIVATE "/Zc:__cplusplus" "/permissive-" "/utf-8") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(Live2DViewer PRIVATE "-Wall" "-Wextra") endif() ``` -------------------------------- ### Off-Screen Vertex Shader Source: https://github.com/easylive2d/live2d-py/blob/main/docs/LIVE2D_V2_RENDERER.md Applies MVP matrix transformations and a separate clip matrix for off-screen rendering. ```glsl attribute vec2 a_position; attribute vec2 a_texCoord; varying vec2 v_texCoord; varying vec4 v_clipPos; uniform mat4 u_mvpMatrix; uniform mat4 u_clipMatrix; void main() { vec4 pos = vec4(a_position, 0, 1.0); gl_Position = u_mvpMatrix * pos; v_clipPos = u_clipMatrix * pos; // 使用不同的裁剪矩阵 v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y; } ``` -------------------------------- ### Component Data Structure Source: https://github.com/easylive2d/live2d-py/wiki/Cubism-Live2D-MOC-相关说明 Structure for a component within a Live2D part, including texture UV map, vertex indices, and pivot points. ```json { "UvMap": [], "IndexArray": [], "PivotPoints": [] } ``` -------------------------------- ### Link Fine-Grained Sources to Target Source: https://github.com/easylive2d/live2d-py/blob/main/Live2D/Main/CMakeLists.txt Links the collected fine-grained source files (FINE_GRAINED_SRCS) to the 'Main' target. This ensures these sources are compiled and included in the final executable or library. ```cmake target_sources(Main PRIVATE ${FINE_GRAINED_SRCS}) ``` -------------------------------- ### Set Console Output Encoding for MSVC Source: https://github.com/easylive2d/live2d-py/blob/main/CMakeLists.txt Ensures correct character encoding for console output when using the MSVC compiler. ```cmake if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") execute_process(COMMAND chcp 65001) endif() ``` -------------------------------- ### Set C++ Standard for macOS Source: https://github.com/easylive2d/live2d-py/blob/main/CMakeLists.txt Sets the C++ standard to C++11 and required for Apple platforms. Configures architecture for M1/M2 chips. ```cmake if(APPLE) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") set(CMAKE_OSX_ARCHITECTURES "arm64") else() set(CMAKE_OSX_ARCHITECTURES "x86_64") endif() endif() ``` -------------------------------- ### Transform Live2D Model (Scale, Offset, Rotation) Source: https://context7.com/easylive2d/live2d-py/llms.txt Adjust the model's position, size, and rotation within the Pygame window. Values for offset are normalized (-1.0 to 1.0). ```python import live2d.v3 as live2d # After loading model... # Set model offset (moves the model within the canvas) # Values are in normalized coordinates (-1.0 to 1.0) model.SetOffset(0.3, -0.2) # Move right and down # Set scale factor (1.0 = default size) model.SetScale(1.5) # 150% size # Rotate the model (degrees, counterclockwise when positive) model.Rotate(15.0) # Rotate 15 degrees counterclockwise # Get canvas information canvas_size = model.GetCanvasSize() # Returns (width, height) in units canvas_pixels = model.GetCanvasSizePixel() # Returns (width, height) in pixels ppu = model.GetPixelsPerUnit() # Pixels per unit ratio ``` -------------------------------- ### Live2D Expression Update Logic Source: https://github.com/easylive2d/live2d-py/wiki/以更细粒度控制-Live2D-模型(编写中) Internal logic for updating expressions, differentiating between a single active expression managed by `_expressionManager` and multiple layered expressions managed by `_expManagers`. ```cpp if (_expressionManager->IsFinished()) { for (auto &pair : _expManagers) { pair.second->UpdateMotion(_model, deltaSecs); } } else { _expressionManager->UpdateMotion(_model, deltaSecs); } ```