PistonDevelopers / mush

gui for dialogue graphs, et al.
Apache License 2.0
12 stars 2 forks source link

Discuss custom graph backend #23

Closed viperscape closed 9 years ago

viperscape commented 9 years ago

I've started working on a custom graph backend as well a trait system to use other libs; I want to share soon as I get something working, but wanted to see exactly what we'll need for this to be useful so starting a discussion.

stjahns commented 9 years ago

Cool!

stjahns commented 9 years ago

The important bits, for me, keeping in mind that I personally want to use this for editing animation blend trees and state machines, would be:

This probably requires a bit more of a specialized structure than just a generic graph.

viperscape commented 9 years ago

I think edges can use an enum to specify connection types under one Type, and you can specify connections from multiple nodes, though probably max 1-1. Does that make sense? Otherwise I think we'll have to use runtime reflection with Any and TypeIds. So far I think hashmap with uuids will work fine, though removing nodes might incur cost, more on that soon. Can you elaborate on the sockets idea and blend trees? I'll read up as well

viperscape commented 9 years ago

So I have a initial rough draft of some working graph code. Take a peek at what it's starting to shape up as. Lots more to do though!

Note that I have very minimal Edge data (just a To-Node and Weight), I think this might be ideal because it's less house keeping, edge's can then be generated at render time with a Uuid of (from.uuid + to.uuid) or something similar perhaps.

stjahns commented 9 years ago

Looking good so far :)

To elaborate, here's a rough drawing of what a blend tree editor could look like:

20150507_130455

This shows a really simple blend tree that blends the output of two animation clips, weighted by some float parameter between 0 and 1. Its important that the editor doesn't let you make invalid connections between sockets, e.g. you shouldn't be able to connect the 'output' socket of one AnimClip to the 'output' socket of another AnimClip, or hook up a float value socket to the 'Input 1' socket of the LerpBlend node.

See here for what the blend tree data looks like, and how I really don't want to force people to edit that by hand :)

stjahns commented 9 years ago

Here's a rough idea of what the data structures could look like to support socket connections:

struct Node {
    // Sockets on the right of the nodes, can only be connected to outputs
    input_sockets: Vec<InputSocketUuid>,

    // Sockets on the left lf the nodes, can only be connected to inputs
    output_sockets: Vec<OutputSocketUuid>,

    // SourceData could be a trait that describes a list of editable properties for the node 
    // (Similar to the old `EditableNode` trait)
    data: Box<SourceData>,
}

type SocketType = String;
struct Socket {
    socket_type: SocketType,

    // Maybe it should also keep track of its node? not sure
    node: NodeUuid,

    label: String,
}

 // Connections should validate that the input and output SocketTypes match
struct Connection{
    input: InputSocketUuid,
    output: OutputSocketUuid,
    data: Box<SourceData>,
}

struct Graph {
    nodes: HashMap<NodeUuid, Node>,

    // Sockets on the right of the nodes, can only be connected to outputs
    input_sockets: HashMap<InputSocketUuid, Socket>,

    // Sockets on the left lf the nodes, can only be connected to inputs
    output_sockets: HashMap<OutputSocketUuid, Socket>,

    // It might be easier to keep the Connection/Edge map on the graph itself, otherwise to
    // identify an edge/connection with its Uuid, we also need to know what its parent node is
    connections: HashMap<ConnectionUuid, Connection>
}

// For a little extra type saftey, we can use different type aliases for Uuid:
type NodeUuid = Uuid;
type InputSocketUuid = Uuid;
type OutputSocketUuid = Uuid;
type ConnectionUuid = Uuid;
stjahns commented 9 years ago

I guess the really big question is that if we also want an editor for a 'simple' graph, where nodes are directly connected by edges, maybe that needs to use a different editor/data structure altogether?

viperscape commented 9 years ago

I feel a bit more confident in the graph code now, so I want to tackle two things: bringing in a trait so the backend can be swapped out for something like petgraph if wanted; and the blend graph with node guards like you are aiming for. I think we can get both a basic graph and a blend graph in one code base

viperscape commented 9 years ago

As seen here I am wondering if it beneficial or necessary to create a transformation trait, and perhaps even some basic functionality for node transformations, such as the mixer in a blend graph. I'm not sure how this would work really, but seeing what I've read up on blend graphs, this seems like a good idea. If the blend will only ever use a single float value(like crouch_run, stand_run, blend_float), it'd be considerably simpler to reuse the edge-weight factors for this; however then a blend is locked in to a single describing factor and that just seems too limiting.

viperscape commented 9 years ago

closed by #24 more discussion on node-connection types can continue here