Skip to content
forked from Inochi2D/inochi2d

Inochi2D reference implementation aimed at rendering 2D puppets that can be animated in real-time (using eg. facial capture).

License

Notifications You must be signed in to change notification settings

Noeme2D/inochi2d

 
 

Repository files navigation

日本語

Inochi2D (OpenGL ES 2.0 Port)

Support me on Patreon Discord

Inochi2D is a library for realtime 2D puppet animation and the reference implementation of the Inochi2D Puppet standard.

Currently this library and the standard is in the prototype stage and is not recommended for production use.
If you want to try it out anyways you can clone this repo and run dub add-local (inochi2d folder) "1.0.0" then manually add it as a dependency in to dub.sdl/json.

 

2022-05-03.02-46-34.mp4

Video from Beta 0.7.2, LunaFoxgirlVT, model art by kpon

 

Rigging

If you're a model rigger you may want to check out Inochi Creator, the official Inochi2D rigging app in development.
This repository is purely for the standard and is not useful if you're an end user.

 

How does Inochi2D work?

Inochi2D contains all your parts (textures) in a tree of Node objects.
Nodes have their own individual purpose.

Parts

Parts contain the actual textures and vertex information of your model.
Each part is an individual texture and set of vertices.

PathDeforms

PathDeforms deform its child Drawables based on its handles.
PathDeforms can deform multiple Drawables at once.

Masks

Masks are a Drawable which allow you to specify a shape.
That shape is used to mask Parts without being a texture itself.

 
More Node types to come...

Do Note

The spec is still work in progress and is subject to change.
More details will be revealed once 1.0 of the spec is released.

 

Bootstrapping Inochi2D

Bootstrapping Inochi2D depends on the backing window managment library you are using.

Inochi2D can be boostrapped in GLFW (bindbc) with the following code

import std.stdio;
import std.getopt;
import std.json;
import std.string;
import inochi2d;
import bindbc.glfw;
import derelict.gles.gles2;

int main() {
    loadGLFW();
    glfwInit();

    glfwWindowHint(GLFW_OPENGL_ES_API, GLFW_OPENGL_ANY_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    GLFWwindow* window = glfwCreateWindow(480, 800, "Inochi2D App".toStringz, null, null);

    glfwMakeContextCurrent(window);
    DerelictGLES2.load();

    // A timing function that returns the current applications runtime in seconds and milliseconds is needed
    inInit(cast(double function())glfwGetTime);

    // Get the viewport size, which is the size of the scene
    int sceneWidth, sceneHeight;

    // It is highly recommended to change the viewport with
    // inSetViewport to match the viewport you want, otherwise it'll be 640x480
    inSetViewport(480, 800);
    inGetViewport(sceneWidth, sceneHeight);

    // Also many vtuber textures are pretty big so let's zoom out a bit.
    inGetCamera().scale = vec2(0.2);
    inGetCamera().position = vec2(0, 1000);

    // NOTE: If you want to implement camera switching (for eg camera presets) use
    // inSetCamera

    // NOTE: Loading API WIP, subject to change
    // You can get example models at https://github.com/Inochi2D/example-models
    Puppet myPuppet = inLoadPuppet("Aka.inx");
    
    // Example of how to retreive and set puppet parameters at runtime
    int[string] name_to_index;
    int index = 0;
    foreach (ref p; myPuppet.parameters) {
        name_to_index[p.name] = index++;
        writeln(p.name);
        writeln(p.isVec2);
    }
    myPuppet.parameters[name_to_index["Head:: Roll"]].value = vec2(-1, 0);

    while(!glfwWindowShouldClose(window)) {
        // NOTE: Inochi2D does not itself clear the main framebuffer
        // you have to do that your self.
        glClear(GL_COLOR_BUFFER_BIT);
        
        // Run inUpdate first
        // This updates various submodules and time managment for animation
        inUpdate();

        // Imagine there's a lot of rendering code here
        // Maybe even some game logic or something

        // Begins drawing in to the Inochi2D scene
        // NOTE: You *need* to do this otherwise rendering may break
        inBeginScene();
        
            // Draw and update myPuppet.
            // Convention for using Inochi2D in D is to put everything
            // in a scene block one indent in.
            myPuppet.update();
            myPuppet.draw();

        // Ends drawing in to the Inochi2D scene.
        inEndScene();
        
        // Draw the scene, background is transparent
        inDrawScene(vec4(0, 0, sceneWidth, sceneHeight));
        
        // Do the buffer swapping and event polling last
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    return 0;
}

NOTE

The version on dub is not always up to date with the newest features, to use inochi2d from the repo either:

  • Add ~master as your version in your dub.selections.json file after having added inochi2d as a dependency.
  • Clone this repo and run dub add-local (inochi2d folder) "1.0.0" to add inochi2d as a local package. You can then add inochi2d as a dependency.

 


The Inochi2D logo was designed by James Daniel

About

Inochi2D reference implementation aimed at rendering 2D puppets that can be animated in real-time (using eg. facial capture).

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • D 97.3%
  • GLSL 2.7%