Exemplo n.º 1
0
from typing import Union

import bpy
from mathutils import Euler, Vector

import arm
import arm.material.cycles as c
import arm.material.cycles_functions as c_functions
from arm.material.parser_state import ParserState
from arm.material.shader import floatstr, vec3str

if arm.is_reload(__name__):
    c = arm.reload_module(c)
    c_functions = arm.reload_module(c_functions)
    arm.material.parser_state = arm.reload_module(arm.material.parser_state)
    from arm.material.parser_state import ParserState
    arm.material.shader = arm.reload_module(arm.material.shader)
    from arm.material.shader import floatstr, vec3str
else:
    arm.enable_reload(__name__)


def parse_curvevec(node: bpy.types.ShaderNodeVectorCurve,
                   out_socket: bpy.types.NodeSocket,
                   state: ParserState) -> vec3str:
    fac = c.parse_value_input(node.inputs[0])
    vec = c.parse_vector_input(node.inputs[1])
    curves = node.mapping.curves
    name = c.node_name(node.name)
    # mapping.curves[0].points[0].handle_type # bezier curve
    return '(vec3({0}, {1}, {2}) * {3})'.format(
Exemplo n.º 2
0
import bpy.types
from bpy.props import *
from nodeitems_utils import NodeItem
from arm.logicnode.arm_sockets import ArmCustomSocket

import arm  # we cannot import arm.livepatch here or we have a circular import
# Pass custom property types and NodeReplacement forward to individual
# node modules that import arm_nodes
from arm.logicnode.arm_props import *
from arm.logicnode.replacement import NodeReplacement
import arm.node_utils
import arm.utils

if arm.is_reload(__name__):
    arm.logicnode.arm_props = arm.reload_module(arm.logicnode.arm_props)
    from arm.logicnode.arm_props import *
    arm.logicnode.replacement = arm.reload_module(arm.logicnode.replacement)
    from arm.logicnode.replacement import NodeReplacement
    arm.node_utils = arm.reload_module(arm.node_utils)
    arm.utils = arm.reload_module(arm.utils)
else:
    arm.enable_reload(__name__)

# When passed as a category to add_node(), this will use the capitalized
# name of the package of the node as the category to make renaming
# categories easier.
PKG_AS_CATEGORY = "__pkgcat__"

nodes = []
category_items: ODict[str, List['ArmNodeCategory']] = OrderedDict()
Exemplo n.º 3
0
import bpy

import arm
import arm.material.cycles as cycles
import arm.material.mat_state as mat_state
import arm.material.make_mesh as make_mesh
import arm.material.make_finalize as make_finalize
import arm.assets as assets

if arm.is_reload(__name__):
    cycles = arm.reload_module(cycles)
    mat_state = arm.reload_module(mat_state)
    make_mesh = arm.reload_module(make_mesh)
    make_finalize = arm.reload_module(make_finalize)
    assets = arm.reload_module(assets)
else:
    arm.enable_reload(__name__)


def make(context_id):
    con_transluc = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise', \
     'blend_source': 'blend_one', 'blend_destination': 'blend_one', 'blend_operation': 'add', \
     'alpha_blend_source': 'blend_zero', 'alpha_blend_destination': 'inverse_source_alpha', 'alpha_blend_operation': 'add' })

    make_mesh.make_forward_base(con_transluc,
                                parse_opacity=True,
                                transluc_pass=True)

    vert = con_transluc.vert
    frag = con_transluc.frag
    tese = con_transluc.tese
Exemplo n.º 4
0
import json
import os
import shutil
import stat
import html
from typing import List

import bpy

import arm.assets as assets
import arm.make_state as state
import arm.utils

if arm.is_reload(__name__):
    import arm
    assets = arm.reload_module(assets)
    state = arm.reload_module(state)
    arm.utils = arm.reload_module(arm.utils)
else:
    arm.enable_reload(__name__)


def on_same_drive(path1: str, path2: str) -> bool:
    drive_path1, _ = os.path.splitdrive(path1)
    drive_path2, _ = os.path.splitdrive(path2)
    return drive_path1 == drive_path2


def add_armory_library(sdk_path: str, name: str, rel_path=False) -> str:
    if rel_path:
        sdk_path = '../' + os.path.relpath(sdk_path, arm.utils.get_fp()).replace('\\', '/')
Exemplo n.º 5
0
import bpy
from bpy.types import NodeSocket

import arm
import arm.material.cycles as c
from arm.material.parser_state import ParserState

if arm.is_reload(__name__):
    c = arm.reload_module(c)
    arm.material.parser_state = arm.reload_module(arm.material.parser_state)
    from arm.material.parser_state import ParserState
else:
    arm.enable_reload(__name__)


def parse_mixshader(node: bpy.types.ShaderNodeMixShader, out_socket: NodeSocket, state: ParserState) -> None:
    prefix = '' if node.inputs[0].is_linked else 'const '
    fac = c.parse_value_input(node.inputs[0])
    fac_var = c.node_name(node.name) + '_fac'
    fac_inv_var = c.node_name(node.name) + '_fac_inv'
    state.curshader.write('{0}float {1} = {2};'.format(prefix, fac_var, fac))
    state.curshader.write('{0}float {1} = 1.0 - {2};'.format(prefix, fac_inv_var, fac_var))
    bc1, rough1, met1, occ1, spec1, opac1, emi1 = c.parse_shader_input(node.inputs[1])
    bc2, rough2, met2, occ2, spec2, opac2, emi2 = c.parse_shader_input(node.inputs[2])
    if state.parse_surface:
        state.out_basecol = '({0} * {3} + {1} * {2})'.format(bc1, bc2, fac_var, fac_inv_var)
        state.out_roughness = '({0} * {3} + {1} * {2})'.format(rough1, rough2, fac_var, fac_inv_var)
        state.out_metallic = '({0} * {3} + {1} * {2})'.format(met1, met2, fac_var, fac_inv_var)
        state.out_occlusion = '({0} * {3} + {1} * {2})'.format(occ1, occ2, fac_var, fac_inv_var)
        state.out_specular = '({0} * {3} + {1} * {2})'.format(spec1, spec2, fac_var, fac_inv_var)
        state.out_emission = '({0} * {3} + {1} * {2})'.format(emi1, emi2, fac_var, fac_inv_var)
Exemplo n.º 6
0
import importlib
import inspect
import pkgutil
import sys

import arm
import arm.logicnode.arm_nodes as arm_nodes
from arm.logicnode.arm_props import *
import arm.logicnode.arm_sockets as arm_sockets
from arm.logicnode.replacement import NodeReplacement

if arm.is_reload(__name__):
    arm_nodes = arm.reload_module(arm_nodes)
    arm.logicnode.arm_props = arm.reload_module(arm.logicnode.arm_props)
    from arm.logicnode.arm_props import *
    arm_sockets = arm.reload_module(arm_sockets)
    arm.logicnode.replacement = arm.reload_module(arm.logicnode.replacement)
    from arm.logicnode.replacement import NodeReplacement

    HAS_RELOADED = True
else:
    arm.enable_reload(__name__)


def init_categories():
    """Register default node menu categories."""
    arm_nodes.add_category(
        'Logic',
        icon='OUTLINER',
        section="basic",
        description=
Exemplo n.º 7
0
import bpy
import nodeitems_utils
from nodeitems_utils import NodeCategory

import arm
import arm.material.arm_nodes.arm_nodes as arm_nodes
# Import all nodes so that they register. Do not remove this import
# even if it looks unused
from arm.material.arm_nodes import *

if arm.is_reload(__name__):
    arm_nodes = arm.reload_module(arm_nodes)
    arm.material.arm_nodes = arm.reload_module(arm.material.arm_nodes)
    from arm.material.arm_nodes import *
else:
    arm.enable_reload(__name__)

registered_nodes = []


class MaterialNodeCategory(NodeCategory):
    @classmethod
    def poll(cls, context):
        return context.space_data.tree_type == 'ShaderNodeTree'


def register_nodes():
    global registered_nodes

    # Re-register all nodes for now..
    if len(registered_nodes) > 0:
Exemplo n.º 8
0
import arm.props_ui
import arm.handlers
import arm.utils
import arm.keymap

reload_started = 0

if arm.is_reload(__name__):
    arm.log.debug('Reloading Armory SDK...')
    reload_started = time.time()

    # Clear the module cache
    import importlib
    arm = importlib.reload(arm)  # type: ignore

    arm.nodes_logic = arm.reload_module(arm.nodes_logic)
    arm.nodes_material = arm.reload_module(arm.nodes_material)
    arm.props_traits_props = arm.reload_module(arm.props_traits_props)
    arm.props_traits = arm.reload_module(arm.props_traits)
    arm.props_lod = arm.reload_module(arm.props_lod)
    arm.props_tilesheet = arm.reload_module(arm.props_tilesheet)
    arm.props_exporter = arm.reload_module(arm.props_exporter)
    arm.props_bake = arm.reload_module(arm.props_bake)
    arm.props_renderpath = arm.reload_module(arm.props_renderpath)
    arm.props_properties = arm.reload_module(arm.props_properties)
    arm.props_collision_filter_mask = arm.reload_module(arm.props_collision_filter_mask)
    arm.props = arm.reload_module(arm.props)
    arm.props_ui = arm.reload_module(arm.props_ui)
    arm.handlers = arm.reload_module(arm.handlers)
    arm.utils = arm.reload_module(arm.utils)
    arm.keymap = arm.reload_module(arm.keymap)
Exemplo n.º 9
0
from contextlib import contextmanager
import math
import multiprocessing
import os
import re
import subprocess

import bpy

import arm.assets as assets
import arm.log as log
import arm.utils

if arm.is_reload(__name__):
    import arm
    assets = arm.reload_module(assets)
    log = arm.reload_module(log)
    arm.utils = arm.reload_module(arm.utils)
else:
    arm.enable_reload(__name__)

# The format used for rendering the environment. Choose HDR or JPEG.
ENVMAP_FORMAT = 'JPEG'
ENVMAP_EXT = 'hdr' if ENVMAP_FORMAT == 'HDR' else 'jpg'


def add_irr_assets(output_file_irr):
    assets.add(output_file_irr + '.arm')


def add_rad_assets(output_file_rad, rad_format, num_mips):
Exemplo n.º 10
0
import bpy

import arm
import arm.material.make_tess as make_tess
from arm.material.shader import ShaderContext

if arm.is_reload(__name__):
    make_tess = arm.reload_module(make_tess)
    arm.material.shader = arm.reload_module(arm.material.shader)
    from arm.material.shader import ShaderContext
else:
    arm.enable_reload(__name__)


def make(con_mesh: ShaderContext):
    vert = con_mesh.vert
    frag = con_mesh.frag
    geom = con_mesh.geom
    tesc = con_mesh.tesc
    tese = con_mesh.tese

    # Additional values referenced in cycles
    # TODO: enable from cycles.py
    if frag.contains('dotNV') and not frag.contains('float dotNV'):
        frag.write_init('float dotNV = max(dot(n, vVec), 0.0);')

        # n is not always defined yet (in some shadowmap shaders e.g.)
        if not frag.contains('vec3 n'):
            vert.add_out('vec3 wnormal')
            vert.add_uniform('mat3 N', '_normalMatrix')
            vert.write_attrib('wnormal = normalize(N * vec3(nor.xy, pos.w));')
Exemplo n.º 11
0
import arm
import arm.material.cycles as cycles
import arm.material.make_shader as make_shader
import arm.material.mat_state as mat_state

if arm.is_reload(__name__):
    cycles = arm.reload_module(cycles)
    make_shader = arm.reload_module(make_shader)
    mat_state = arm.reload_module(mat_state)
else:
    arm.enable_reload(__name__)

# TODO: handle groups
# TODO: handle cached shaders

batchDict = None
signatureDict = None

def traverse_tree(node, sign):
    sign += node.type + '-'
    for inp in node.inputs:
        if inp.is_linked:
            sign = traverse_tree(inp.links[0].from_node, sign)
        else:
            sign += 'o' # Unconnected socket
    return sign

def get_signature(mat):
    nodes = mat.node_tree.nodes
    output_node = cycles.node_by_type(nodes, 'OUTPUT_MATERIAL')
Exemplo n.º 12
0
import arm
import arm.material.make_finalize as make_finalize
import arm.material.make_mesh as make_mesh
import arm.material.mat_state as mat_state
import arm.material.mat_utils as mat_utils

if arm.is_reload(__name__):
    make_finalize = arm.reload_module(make_finalize)
    make_mesh = arm.reload_module(make_mesh)
    mat_state = arm.reload_module(mat_state)
    mat_utils = arm.reload_module(mat_utils)
else:
    arm.enable_reload(__name__)


def make(context_id):
    con = {
        'name': context_id,
        'depth_write': True,
        'compare_mode': 'less',
        'cull_mode': 'clockwise'
    }
    mat = mat_state.material
    blend = mat.arm_blending
    if blend:
        con['blend_source'] = mat.arm_blending_source
        con['blend_destination'] = mat.arm_blending_destination
        con['blend_operation'] = mat.arm_blending_operation
        con['alpha_blend_source'] = mat.arm_blending_source_alpha
        con['alpha_blend_destination'] = mat.arm_blending_destination_alpha
        con['alpha_blend_operation'] = mat.arm_blending_operation_alpha
Exemplo n.º 13
0
from bpy.props import *
from bpy.types import Node

import arm
from arm.material.arm_nodes.arm_nodes import add_node
from arm.material.shader import Shader

if arm.is_reload(__name__):
    arm.material.arm_nodes.arm_nodes = arm.reload_module(
        arm.material.arm_nodes.arm_nodes)
    from arm.material.arm_nodes.arm_nodes import add_node
    arm.material.shader = arm.reload_module(arm.material.shader)
    from arm.material.shader import Shader
else:
    arm.enable_reload(__name__)


class ShaderDataNode(Node):
    """Allows access to shader data such as uniforms and inputs."""
    bl_idname = 'ArmShaderDataNode'
    bl_label = 'Shader Data'
    bl_icon = 'NONE'

    input_type: EnumProperty(
        items=[('input', 'Input', 'Shader Input'),
               ('uniform', 'Uniform', 'Uniform value')],
        name='Input Type',
        default='input',
        description="The kind of data that should be retrieved")

    input_source: EnumProperty(items=[
Exemplo n.º 14
0
import bpy
from bpy.app.handlers import persistent

import arm
import arm.api
import arm.live_patch as live_patch
import arm.logicnode.arm_nodes as arm_nodes
import arm.nodes_logic
import arm.make as make
import arm.make_state as state
import arm.props as props
import arm.utils

if arm.is_reload(__name__):
    arm.api = arm.reload_module(arm.api)
    live_patch = arm.reload_module(live_patch)
    arm_nodes = arm.reload_module(arm_nodes)
    arm.nodes_logic = arm.reload_module(arm.nodes_logic)
    make = arm.reload_module(make)
    state = arm.reload_module(state)
    props = arm.reload_module(props)
    arm.utils = arm.reload_module(arm.utils)
else:
    arm.enable_reload(__name__)


@persistent
def on_depsgraph_update_post(self):
    if state.proc_build != None:
        return
Exemplo n.º 15
0
from enum import IntEnum, unique
from typing import List, Set, Tuple, Union, Optional

import bpy

import arm
from arm.material.shader import Shader, ShaderContext, vec3str, floatstr

if arm.is_reload(__name__):
    arm.material.shader = arm.reload_module(arm.material.shader)
    from arm.material.shader import Shader, ShaderContext, vec3str, floatstr
else:
    arm.enable_reload(__name__)

    @unique
    class ParserContext(IntEnum):
        """Describes which kind of node tree is parsed."""
        OBJECT = 0
        # Texture node trees are not supported yet
        # TEXTURE = 1
        WORLD = 2


class ParserState:
    """Dataclass to keep track of the current state while parsing a shader tree."""
    def __init__(self,
                 context: ParserContext,
                 tree_name: str,
                 world: Optional[bpy.types.World] = None):
        self.context = context
        self.tree_name = tree_name
Exemplo n.º 16
0
import cProfile
import os
import pstats

import arm
import arm.log as log
import arm.utils as utils

if arm.is_reload(__name__):
    log = arm.reload_module(log)
    utils = arm.reload_module(utils)
else:
    arm.enable_reload(__name__)


class Profile:
    """Context manager for profiling the enclosed code when the given condition is true.
    The output file is stored in the SDK directory and can be opened by tools such as SnakeViz.
    """
    def __init__(self, filename_out: str, condition: bool):
        self.filename_out = filename_out
        self.condition = condition
        self.pr = cProfile.Profile()

    def __enter__(self):
        if self.condition:
            self.pr.enable()
            log.debug("Profiling started")

        return self
Exemplo n.º 17
0
import bpy

import arm
import arm.log as log
import arm.props_ui as props_ui

if arm.is_reload(__name__):
    props_ui = arm.reload_module(props_ui)
else:
    arm.enable_reload(__name__)

arm_keymaps = []


def register():
    wm = bpy.context.window_manager
    addon_keyconfig = wm.keyconfigs.addon

    # Keyconfigs are not available in background mode. If the keyconfig
    # was not found despite running _not_ in background mode, a warning
    # is printed
    if addon_keyconfig is None:
        if not bpy.app.background:
            log.warn("No keyconfig path found")
        return

    km = addon_keyconfig.keymaps.new(name='Window',
                                     space_type='EMPTY',
                                     region_type="WINDOW")
    km.keymap_items.new(props_ui.ArmoryPlayButton.bl_idname,
                        type='F5',