Logic fixes, primitive events

This commit is contained in:
Lubos Lenco 2017-04-16 14:46:35 +02:00
parent 795726b28b
commit 5e736a615f
38 changed files with 367 additions and 27 deletions

View file

@ -2,6 +2,9 @@ package armory.logicnode;
import armory.object.Object;
import armory.math.Mat4;
#if arm_physics
import armory.trait.internal.RigidBody;
#end
class AppendTransformNode extends LogicNode {
@ -17,6 +20,14 @@ class AppendTransformNode extends LogicNode {
object.transform.multMatrix(matrix);
#if arm_physics
var rigidBody = object.getTrait(RigidBody);
if (rigidBody != null) {
rigidBody.syncTransform();
rigidBody.activate();
}
#end
super.run();
}
}

View file

@ -9,6 +9,7 @@ class ArrayGetNode extends LogicNode {
override function get(from:Int):Dynamic {
var ar:Array<Dynamic> = inputs[0].get();
var i:Int = inputs[1].get();
if (i < 0) i = ar.length + i;
return ar[i];
}
}

View file

@ -0,0 +1,13 @@
package armory.logicnode;
class ArrayPopNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from:Int):Dynamic {
var ar:Array<Dynamic> = inputs[0].get();
return ar.pop();
}
}

View file

@ -2,15 +2,24 @@ package armory.logicnode;
class ArrayRemoveNode extends LogicNode {
var removedValue:Dynamic = null;
public function new(tree:LogicTree) {
super(tree);
}
override function run() {
var ar:Array<Dynamic> = inputs[1].get();
var index:Int = inputs[2].get();
ar.splice(index, 1);
var i:Int = inputs[2].get();
if (i < 0) i = ar.length + i;
super.run();
removedValue = ar[i];
ar.splice(i, 1);
runOutputs(0);
}
override function get(from:Int):Dynamic {
return removedValue;
}
}

View file

@ -10,7 +10,9 @@ class ArraySetNode extends LogicNode {
var ar:Array<Dynamic> = inputs[1].get();
var i:Int = inputs[2].get();
var value:Dynamic = inputs[3].get();
ar[i] = value;
if (i < 0) ar[ar.length + i] = value;
else ar[i] = value;
super.run();
}

View file

@ -0,0 +1,13 @@
package armory.logicnode;
class ArrayShiftNode extends LogicNode {
public function new(tree:LogicTree) {
super(tree);
}
override function get(from:Int):Dynamic {
var ar:Array<Dynamic> = inputs[0].get();
return ar.shift();
}
}

View file

@ -12,6 +12,6 @@ class GetDistanceNode extends LogicNode {
var object1:Object = inputs[0].get();
var object2:Object = inputs[1].get();
return armory.math.Vec4.distance3d(object1.transform.loc, object2.transform.loc);
return armory.math.Vec4.distance3d(object1.transform.abs, object2.transform.abs);
}
}

View file

@ -13,6 +13,6 @@ class GetLocationNode extends LogicNode {
if (object == null) object = tree.object;
return object.transform.loc;
return object.transform.abs;
}
}

View file

@ -19,7 +19,7 @@ class GoToLocationNode extends LogicNode {
#if arm_navigation
// Assume navmesh exists..
var from = object.transform.loc;
var from = object.transform.abs;
var to = location;
Navigation.active.navMeshes[0].findPath(from, to, function(path:Array<iron.math.Vec4>) {
var agent:armory.trait.NavAgent = object.getTrait(armory.trait.NavAgent);

View file

@ -0,0 +1,24 @@
package armory.logicnode;
class OnEventNode extends LogicNode {
var _property0:String;
public var property0(get, set):String;
public function new(tree:LogicTree) {
super(tree);
}
function get_property0():String {
return _property0;
}
function set_property0(s:String):String {
armory.system.Event.add(s, onEvent, tree.object.uid);
return _property0 = s;
}
function onEvent() {
run();
}
}

View file

@ -14,6 +14,7 @@ class OnGamepadNode extends LogicNode {
function update() {
var num:Int = inputs[0].get();
var gamepad = armory.system.Input.getGamepad(num);
if (gamepad == null) return;
var b = false;
switch (property0) {
case "Down":

View file

@ -4,6 +4,9 @@ import armory.object.Object;
import armory.math.Mat4;
import armory.math.Quat;
import armory.math.Vec4;
#if arm_physics
import armory.trait.internal.RigidBody;
#end
class RotateObjectNode extends LogicNode {
@ -24,6 +27,14 @@ class RotateObjectNode extends LogicNode {
object.transform.rot.mult(q);
object.transform.buildMatrix();
#if arm_physics
var rigidBody = object.getTrait(RigidBody);
if (rigidBody != null) {
rigidBody.syncTransform();
rigidBody.activate();
}
#end
super.run();
}
}

View file

@ -3,6 +3,9 @@ package armory.logicnode;
import armory.object.Object;
import armory.math.Mat4;
import armory.math.Vec4;
#if arm_physics
import armory.trait.internal.RigidBody;
#end
class ScaleObjectNode extends LogicNode {
@ -19,6 +22,14 @@ class ScaleObjectNode extends LogicNode {
object.transform.scale.add(vec);
object.transform.buildMatrix();
#if arm_physics
var rigidBody = object.getTrait(RigidBody);
if (rigidBody != null) {
rigidBody.syncTransform();
rigidBody.activate();
}
#end
super.run();
}
}

View file

@ -0,0 +1,28 @@
package armory.logicnode;
import armory.object.Object;
import armory.system.Event;
class SendEventNode extends LogicNode {
var entries:Array<TEvent> = null;
public function new(tree:LogicTree) {
super(tree);
}
override function run() {
var name:String = inputs[1].get();
if (entries == null) {
var all = armory.system.Event.get(name);
if (all != null) {
entries = [];
for (e in all) if (e.mask == tree.object.uid) entries.push(e);
}
}
for (e in entries) e.onEvent();
super.run();
}
}

View file

@ -0,0 +1,22 @@
package armory.logicnode;
import armory.object.Object;
import armory.system.Event;
class SendGlobalEventNode extends LogicNode {
var entries:Array<TEvent> = null;
public function new(tree:LogicTree) {
super(tree);
}
override function run() {
var name:String = inputs[1].get();
if (entries == null) entries = armory.system.Event.get(name);
for (e in entries) e.onEvent();
super.run();
}
}

View file

@ -2,6 +2,9 @@ package armory.logicnode;
import armory.object.Object;
import armory.math.Vec4;
#if arm_physics
import armory.trait.internal.RigidBody;
#end
class SetLocationNode extends LogicNode {
@ -18,6 +21,14 @@ class SetLocationNode extends LogicNode {
object.transform.loc.setFrom(vec);
object.transform.buildMatrix();
#if arm_physics
var rigidBody = object.getTrait(RigidBody);
if (rigidBody != null) {
rigidBody.syncTransform();
rigidBody.activate();
}
#end
super.run();
}
}

View file

@ -2,6 +2,9 @@ package armory.logicnode;
import armory.object.Object;
import armory.math.Vec4;
#if arm_physics
import armory.trait.internal.RigidBody;
#end
class SetRotationNode extends LogicNode {
@ -18,6 +21,14 @@ class SetRotationNode extends LogicNode {
object.transform.rot.fromEuler(vec);
object.transform.buildMatrix();
#if arm_physics
var rigidBody = object.getTrait(RigidBody);
if (rigidBody != null) {
rigidBody.syncTransform();
rigidBody.activate();
}
#end
super.run();
}
}

View file

@ -2,6 +2,9 @@ package armory.logicnode;
import armory.object.Object;
import armory.math.Vec4;
#if arm_physics
import armory.trait.internal.RigidBody;
#end
class SetScaleNode extends LogicNode {
@ -18,6 +21,14 @@ class SetScaleNode extends LogicNode {
object.transform.scale.setFrom(vec);
object.transform.buildMatrix();
#if arm_physics
var rigidBody = object.getTrait(RigidBody);
if (rigidBody != null) {
rigidBody.syncTransform();
rigidBody.activate();
}
#end
super.run();
}
}

View file

@ -2,6 +2,9 @@ package armory.logicnode;
import armory.object.Object;
import armory.math.Mat4;
#if arm_physics
import armory.trait.internal.RigidBody;
#end
class SetTransformNode extends LogicNode {
@ -17,6 +20,14 @@ class SetTransformNode extends LogicNode {
object.transform.setMatrix(matrix);
#if arm_physics
var rigidBody = object.getTrait(RigidBody);
if (rigidBody != null) {
rigidBody.syncTransform();
rigidBody.activate();
}
#end
super.run();
}
}

View file

@ -13,12 +13,12 @@ class SpawnObjectNode extends LogicNode {
override function run() {
var objectName:String = cast(inputs[1].node, ObjectNode).property0;
var objectName:String = cast(inputs[1].node, ObjectNode).objectName;
var matrix:Mat4 = inputs[2].get();
Scene.active.spawnObject(objectName, null, function(o:armory.object.Object) {
object = o;
object.transform.setMatrix(matrix);
if (matrix != null) object.transform.setMatrix(matrix);
object.visible = true;
runOutputs(0);
});

View file

@ -3,6 +3,9 @@ package armory.logicnode;
import armory.object.Object;
import armory.math.Mat4;
import armory.math.Vec4;
#if arm_physics
import armory.trait.internal.RigidBody;
#end
class TranslateObjectNode extends LogicNode {
@ -19,6 +22,14 @@ class TranslateObjectNode extends LogicNode {
object.transform.loc.add(vec);
object.transform.buildMatrix();
#if arm_physics
var rigidBody = object.getTrait(RigidBody);
if (rigidBody != null) {
rigidBody.syncTransform();
rigidBody.activate();
}
#end
super.run();
}
}

View file

@ -0,0 +1,31 @@
package armory.system;
class Event {
static var events = new Map<String, Array<TEvent>>();
public static function send(name:String, mask = -1) {
var entries = get(name);
for (e in entries) if (mask == -1 || mask == e.mask ) e.onEvent();
}
public static function get(name:String):Array<TEvent> {
return events.get(name);
}
public static function add(name:String, onEvent:Void->Void, mask = -1) {
var e:TEvent = { onEvent: onEvent, mask: mask };
var entries = events.get(name);
if (entries != null) entries.push(e);
else events.set(name, [e]);
}
public static function remove(name:String) {
events.remove(name);
}
}
typedef TEvent = {
public var onEvent:Void->Void;
public var mask:Int;
}

View file

@ -48,12 +48,10 @@ class RigidBody extends Trait {
this.linearDamping = linearDamping;
this.angularDamping = angularDamping;
this.passive = passive;
Scene.active.notifyOnInit(function() {
notifyOnInit(init);
notifyOnLateUpdate(lateUpdate);
notifyOnRemove(removeFromWorld);
});
notifyOnAdd(init);
notifyOnLateUpdate(lateUpdate);
notifyOnRemove(removeFromWorld);
}
inline function withMargin(f:Float) {

View file

@ -0,0 +1,16 @@
import bpy
from bpy.props import *
from bpy.types import Node, NodeSocket
from arm.logicnode.arm_nodes import *
class ArrayPopNode(Node, ArmLogicTreeNode):
'''Array pop node'''
bl_idname = 'LNArrayPopNode'
bl_label = 'Array Pop'
bl_icon = 'GAME'
def init(self, context):
self.inputs.new('NodeSocketShader', 'Array')
self.outputs.new('NodeSocketShader', 'Value')
add_node(ArrayPopNode, category='Action')

View file

@ -14,5 +14,6 @@ class ArrayRemoveNode(Node, ArmLogicTreeNode):
self.inputs.new('NodeSocketShader', 'Array')
self.inputs.new('NodeSocketInt', 'Index')
self.outputs.new('ArmNodeSocketAction', 'Out')
self.outputs.new('NodeSocketShader', 'Value')
add_node(ArrayRemoveNode, category='Action')

View file

@ -0,0 +1,16 @@
import bpy
from bpy.props import *
from bpy.types import Node, NodeSocket
from arm.logicnode.arm_nodes import *
class ArrayShiftNode(Node, ArmLogicTreeNode):
'''Array shift node'''
bl_idname = 'LNArrayShiftNode'
bl_label = 'Array Shift'
bl_icon = 'GAME'
def init(self, context):
self.inputs.new('NodeSocketShader', 'Array')
self.outputs.new('NodeSocketShader', 'Value')
add_node(ArrayShiftNode, category='Action')

View file

@ -0,0 +1,17 @@
import bpy
from bpy.props import *
from bpy.types import Node, NodeSocket
from arm.logicnode.arm_nodes import *
class SendEventNode(Node, ArmLogicTreeNode):
'''Send event node'''
bl_idname = 'LNSendEventNode'
bl_label = 'Send Event'
bl_icon = 'CURVE_PATH'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')
self.inputs.new('NodeSocketString', 'Event')
self.outputs.new('ArmNodeSocketAction', 'Out')
add_node(SendEventNode, category='Action')

View file

@ -0,0 +1,17 @@
import bpy
from bpy.props import *
from bpy.types import Node, NodeSocket
from arm.logicnode.arm_nodes import *
class SendGlobalEventNode(Node, ArmLogicTreeNode):
'''Send global event node'''
bl_idname = 'LNSendGlobalEventNode'
bl_label = 'Send Global Event'
bl_icon = 'CURVE_PATH'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')
self.inputs.new('NodeSocketString', 'Event')
self.outputs.new('ArmNodeSocketAction', 'Out')
add_node(SendGlobalEventNode, category='Action')

View file

@ -48,8 +48,10 @@ class ArmObjectSocket(bpy.types.NodeSocket):
def draw(self, context, layout, node, text):
if self.is_output:
layout.label(self.name)
elif self.is_linked:
layout.label(self.name)
else:
row = layout.row(align = True)
row = layout.row(align=True)
row.prop_search(self, 'default_value', bpy.context.scene, 'objects', icon='NONE', text='')
op = row.operator('arm.node_eyedrop', text='', icon='EYEDROPPER', emboss=True)
op.socket_index = str(id(self))

View file

@ -0,0 +1,19 @@
import bpy
from bpy.props import *
from bpy.types import Node, NodeSocket
from arm.logicnode.arm_nodes import *
class OnEventNode(Node, ArmLogicTreeNode):
'''On event node'''
bl_idname = 'LNOnEventNode'
bl_label = 'On Event'
bl_icon = 'CURVE_PATH'
property0 = StringProperty(name='', default='')
def init(self, context):
self.outputs.new('ArmNodeSocketAction', 'Out')
def draw_buttons(self, context, layout):
layout.prop(self, 'property0')
add_node(OnEventNode, category='Event')

View file

@ -364,8 +364,10 @@ def play_project(in_viewport):
scripts_mtime = mtime
wrd.arm_recompile = True
if state.krom_running: # TODO: Temp live-patch fix till compiler cache is disabled
compile_project(target_name=state.target, patch=True)
# New compile requred - traits or materials changed
if wrd.arm_recompile or state.target == 'native':
elif wrd.arm_recompile or state.target == 'native':
# Unable to live-patch, stop player
if state.krom_running:

View file

@ -11,6 +11,9 @@ def make_renderer(cam):
global nodes
global links
if bpy.data.filepath.endswith('arm_data.blend'): # Prevent load in library itself
return
if cam.rp_renderer == 'Forward':
load_library('forward_path', 'armory_default')
group = bpy.data.node_groups['armory_default']
@ -52,6 +55,13 @@ def make_forward(cam):
relink('Bind Target Mesh SM', 'Draw Meshes Mesh') # No shadowmap bind
relink('Bind Target Transluc SM', 'Draw Meshes Transluc')
if cam.rp_stereo:
if cam.rp_shadowmap != 'None':
links.new(nodes['Bind Target Mesh SM'].outputs[0], nodes['Draw Stereo'].inputs[0])
else:
links.new(nodes['Clear Target Mesh'].outputs[0], nodes['Draw Stereo'].inputs[0])
links.new(nodes['Draw Stereo'].outputs[1], nodes['Draw Meshes Mesh'].inputs[0])
if not cam.rp_worldnodes:
relink('Draw World', 'Set Target Accum')
nodes['Clear Target Mesh'].inputs[1].default_value = True
@ -175,8 +185,10 @@ def reload_blend_data():
check_default()
def load_library(asset_name, rename=None):
if bpy.data.filepath.endswith('arm_data.blend'): # Prevent load in library itself
return
sdk_path = arm.utils.get_sdk_path()
data_path = sdk_path + '/armory/blender/data/data.blend'
data_path = sdk_path + '/armory/blender/data/arm_data.blend'
data_names = [asset_name]
# Remove old

View file

@ -25,9 +25,8 @@ str_tex_voronoi = """//vec3 hash(vec3 x) {
//return fract(sin(x) * 43758.5453123);
//}
vec4 tex_voronoi(const vec3 x) {
vec3 xx = x * 20.0; // Match cycles
vec3 p = floor(xx);
vec3 f = fract(xx);
vec3 p = floor(x);
vec3 f = fract(x);
float id = 0.0;
float res = 100.0;
for (int k = -1; k <= 1; k++)
@ -113,10 +112,10 @@ float tex_noise_f(const vec3 p) {
return clamp(dot(d, vec4(52.0)), 0.0, 1.0);
}
float tex_noise(const vec3 p) {
return 0.5333333 * tex_noise_f(p)
+ 0.2666667 * tex_noise_f(2.0 * p)
+ 0.1333333 * tex_noise_f(4.0 * p)
+ 0.0666667 * tex_noise_f(8.0 * p);
return 0.5333333 * tex_noise_f(0.5 * p)
+ 0.2666667 * tex_noise_f(p)
+ 0.1333333 * tex_noise_f(2.0 * p)
+ 0.0666667 * tex_noise_f(4.0 * p);
}
float tex_noise(const vec2 p) {
return tex_noise(vec3(p.x, p.y, 1.0));

View file

@ -357,7 +357,7 @@ def make_forward_base(con_mesh, parse_opacity=False):
else:
frag.add_include('../../Shaders/std/shadows.glsl')
frag.add_uniform('sampler2D shadowMap', included=True)
frag.add_uniform('sampler2D shadowMapCube', included=True)
frag.add_uniform('samplerCube shadowMapCube', included=True)
frag.add_uniform('bool receiveShadow')
frag.add_uniform('float shadowsBias', '_lampShadowsBias')
frag.add_uniform('int lightShadow', '_lampCastShadow')

View file

@ -224,7 +224,16 @@ def write_indexhtml(w, h):
<title>Armory</title>
</head>
<body>
<canvas id='khanvas' width='""" + str(w) + """' height='""" + str(h) + """'></canvas>
""")
if bpy.data.cameras[0].rp_stereo:
f.write("""
<canvas style="outline: none; position: absolute; left: 0; top: 0;" id='khanvas' width='""" + str(w) + """' height='""" + str(h) + """'></canvas>
""")
else:
f.write("""
<p align="center"><canvas style="outline: none;" id='khanvas' width='""" + str(w) + """' height='""" + str(h) + """'></canvas></p>
""")
f.write("""
<script src='kha.js'></script>
</body>
</html>