Merge pull request #1058 from armory3d/dev

Dev
This commit is contained in:
Lubos Lenco 2018-12-21 12:28:53 +01:00 committed by GitHub
commit b9c3337428
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
249 changed files with 2586 additions and 2777 deletions

View file

@ -105,24 +105,33 @@ uniform vec2 cameraPlane;
#endif
#ifdef _ShadowMap
//!uniform vec2 lightProj;
// uniform samplerCubeShadow shadowMapPoint[4]; //arm_dev
//!uniform samplerCube shadowMapPoint[4];
#ifdef _SinglePoint
#ifdef _Spot
//!uniform sampler2D shadowMapSpot[4];
//!uniform sampler2DShadow shadowMapSpot[1];
//!uniform mat4 LWVPSpot0;
#else
//!uniform samplerCubeShadow shadowMapPoint[1];
//!uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
//!uniform samplerCubeShadow shadowMapPoint[4];
//!uniform vec2 lightProj;
#ifdef _Spot
//!uniform sampler2DShadow shadowMapSpot[4];
//!uniform mat4 LWVPSpot0;
//!uniform mat4 LWVPSpot1;
//!uniform mat4 LWVPSpot2;
//!uniform mat4 LWVPSpot3;
#endif
#endif
#endif
#ifdef _Sun
uniform vec3 sunDir;
uniform vec3 sunCol;
#ifdef _ShadowMap
// uniform sampler2DShadow shadowMap; // arm_dev
uniform sampler2D shadowMap;
uniform sampler2DShadow shadowMap;
uniform float shadowsBias;
#ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4];

View file

@ -44,24 +44,33 @@ uniform vec2 cameraPlane;
#endif
#ifdef _ShadowMap
//!uniform vec2 lightProj;
// uniform samplerCubeShadow shadowMapPoint[4]; //arm_dev
//!uniform samplerCube shadowMapPoint[4];
#ifdef _SinglePoint
#ifdef _Spot
//!uniform sampler2D shadowMapSpot[4];
//!uniform sampler2DShadow shadowMapSpot[1];
//!uniform mat4 LWVPSpot0;
#else
//!uniform samplerCubeShadow shadowMapPoint[1];
//!uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
//!uniform samplerCubeShadow shadowMapPoint[4];
//!uniform vec2 lightProj;
#ifdef _Spot
//!uniform sampler2DShadow shadowMapSpot[4];
//!uniform mat4 LWVPSpot0;
//!uniform mat4 LWVPSpot1;
//!uniform mat4 LWVPSpot2;
//!uniform mat4 LWVPSpot3;
#endif
#endif
#endif
#ifdef _Sun
uniform vec3 sunDir;
uniform vec3 sunCol;
#ifdef _ShadowMap
// uniform sampler2DShadow shadowMap; // arm_dev
uniform sampler2D shadowMap;
uniform sampler2DShadow shadowMap;
uniform float shadowsBias;
#ifdef _CSM
//!uniform vec4 casData[shadowmapCascades * 4 + 4];

View file

@ -4,9 +4,9 @@
#include "std/gbuffer.glsl"
uniform samplerCube probeTex;
uniform sampler2D gbufferD;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbufferD;
uniform mat4 invVP;
uniform vec3 probep;
uniform vec3 eye;

View file

@ -39,6 +39,9 @@ void main() {
vec3 wp = getPos2(invVP, depth, texCoord);
vec4 pp = probeVP * vec4(wp.xyz, 1.0);
vec2 tc = (pp.xy / pp.w) * 0.5 + 0.5;
#ifdef HLSL
tc.y = 1.0 - tc.y;
#endif
vec2 enc = g0.rg;
vec3 n;

View file

@ -9,17 +9,27 @@
#endif
#ifdef _ShadowMap
uniform vec2 lightProj;
// uniform samplerCubeShadow shadowMapPoint[4]; //arm_dev
uniform samplerCube shadowMapPoint[4];
#ifdef _SinglePoint
#ifdef _Spot
uniform sampler2D shadowMapSpot[4];
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot0;
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
uniform samplerCubeShadow shadowMapPoint[4];
uniform vec2 lightProj;
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[4];
uniform mat4 LWVPSpot0;
uniform mat4 LWVPSpot1;
uniform mat4 LWVPSpot2;
uniform mat4 LWVPSpot3;
#endif
#endif
#endif
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
const vec3 albedo, const float rough, const float spec, const vec3 f0
@ -51,22 +61,28 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
direct *= smoothstep(spotB, spotA, spotEffect);
}
#ifdef _ShadowMap
if (index == 0) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias, shadowmapSize);
}
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias, shadowmapSize);
}
#endif
#endif
return direct;
}
@ -95,11 +111,17 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
// #endif
#ifdef _ShadowMap
// Oh well..
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
#endif
#endif
#ifdef _Clusters
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
#endif
return direct;

View file

@ -8,17 +8,27 @@
#endif
#ifdef _ShadowMap
uniform vec2 lightProj;
// uniform samplerCubeShadow shadowMapPoint[4]; //arm_dev
uniform samplerCube shadowMapPoint[4];
#ifdef _SinglePoint
#ifdef _Spot
uniform sampler2D shadowMapSpot[4];
uniform sampler2DShadow shadowMapSpot[1];
uniform mat4 LWVPSpot0;
#else
uniform samplerCubeShadow shadowMapPoint[1];
uniform vec2 lightProj;
#endif
#endif
#ifdef _Clusters
uniform samplerCubeShadow shadowMapPoint[4];
uniform vec2 lightProj;
#ifdef _Spot
uniform sampler2DShadow shadowMapSpot[4];
uniform mat4 LWVPSpot0;
uniform mat4 LWVPSpot1;
uniform mat4 LWVPSpot2;
uniform mat4 LWVPSpot3;
#endif
#endif
#endif
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
const vec3 albedo, const float rough, const float spec, const vec3 f0
@ -50,32 +60,43 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
direct *= smoothstep(spotB, spotA, spotEffect);
}
#ifdef _ShadowMap
if (index == 0) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias, shadowmapSize);
}
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias, shadowmapSize);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias, shadowmapSize);
}
#endif
#endif
return direct;
}
#endif
#ifdef _ShadowMap
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#ifdef _SinglePoint
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
#endif
#ifdef _Clusters
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
#endif
return direct;

View file

@ -7,34 +7,6 @@
uniform vec4 casData[shadowmapCascades * 4 + 4];
#endif
float shadowLerp(sampler2D shadowMap, const vec2 uv, const float compare, const vec2 smSize) {
const vec2 texelSize = vec2(1.0) / smSize;
vec2 f = fract(uv * smSize + 0.5);
vec2 centroidUV = floor(uv * smSize + 0.5) / smSize;
float lb = step(compare, texture(shadowMap, centroidUV).r);
float lt = step(compare, texture(shadowMap, centroidUV + texelSize * vec2(0.0, 1.0)).r);
float rb = step(compare, texture(shadowMap, centroidUV + texelSize * vec2(1.0, 0.0)).r);
float rt = step(compare, texture(shadowMap, centroidUV + texelSize).r);
float a = mix(lb, lt, f.y);
float b = mix(rb, rt, f.y);
float c = mix(a, b, f.x);
return c;
}
float PCF(sampler2D shadowMap, const vec2 uv, const float compare, const vec2 smSize) {
float result = shadowLerp(shadowMap, uv + (vec2(-1.0, -1.0) / smSize), compare, smSize);
result += shadowLerp(shadowMap, uv + (vec2(-1.0, 0.0) / smSize), compare, smSize);
result += shadowLerp(shadowMap, uv + (vec2(-1.0, 1.0) / smSize), compare, smSize);
result += shadowLerp(shadowMap, uv + (vec2(0.0, -1.0) / smSize), compare, smSize);
result += shadowLerp(shadowMap, uv, compare, smSize);
result += shadowLerp(shadowMap, uv + (vec2(0.0, 1.0) / smSize), compare, smSize);
result += shadowLerp(shadowMap, uv + (vec2(1.0, -1.0) / smSize), compare, smSize);
result += shadowLerp(shadowMap, uv + (vec2(1.0, 0.0) / smSize), compare, smSize);
result += shadowLerp(shadowMap, uv + (vec2(1.0, 1.0) / smSize), compare, smSize);
return result / 9.0;
}
// arm_dev
float PCF(sampler2DShadow shadowMap, const vec2 uv, const float compare, const vec2 smSize) {
float result = texture(shadowMap, vec3(uv + (vec2(-1.0, -1.0) / smSize), compare));
result += texture(shadowMap, vec3(uv + (vec2(-1.0, 0.0) / smSize), compare));
@ -55,23 +27,6 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
return zcomp * 0.5 + 0.5;
}
float PCFCube(samplerCube shadowMapCube, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n) {
// return float(texture(shadowMapCube, ml).r + bias > lpToDepth(lp, lightProj));
const float s = shadowmapCubePcfSize; // TODO: incorrect...
float compare = lpToDepth(lp - n * bias * 80, lightProj);
ml = ml + n * bias * 80;
float result = step(compare, texture(shadowMapCube, ml).r);
result += step(compare, texture(shadowMapCube, ml + vec3(s, s, s)).r);
result += step(compare, texture(shadowMapCube, ml + vec3(-s, s, s)).r);
result += step(compare, texture(shadowMapCube, ml + vec3(s, -s, s)).r);
result += step(compare, texture(shadowMapCube, ml + vec3(s, s, -s)).r);
result += step(compare, texture(shadowMapCube, ml + vec3(-s, -s, s)).r);
result += step(compare, texture(shadowMapCube, ml + vec3(s, -s, -s)).r);
result += step(compare, texture(shadowMapCube, ml + vec3(-s, s, -s)).r);
result += step(compare, texture(shadowMapCube, ml + vec3(-s, -s, -s)).r);
return result / 9.0;
}
float PCFCube(samplerCubeShadow shadowMapCube, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n) {
const float s = shadowmapCubePcfSize; // TODO: incorrect...
float compare = lpToDepth(lp - n * bias * 80, lightProj);
@ -88,12 +43,6 @@ float PCFCube(samplerCubeShadow shadowMapCube, const vec3 lp, vec3 ml, const flo
return result / 9.0;
}
float shadowTest(sampler2D shadowMap, const vec3 lPos, const float shadowsBias, const vec2 smSize) {
if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return 1.0;
return PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);
}
// arm_dev
float shadowTest(sampler2DShadow shadowMap, const vec3 lPos, const float shadowsBias, const vec2 smSize) {
if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return 1.0;
return PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);
@ -132,50 +81,6 @@ mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
// ..
}
float shadowTestCascade(sampler2D shadowMap, const vec3 eye, const vec3 p, const float shadowsBias, const vec2 smSize) {
const int c = shadowmapCascades;
float d = distance(eye, p);
int casi;
int casIndex;
mat4 LWVP = getCascadeMat(d, casi, casIndex);
vec4 lPos = LWVP * vec4(p, 1.0);
float visibility = 1.0;
if (lPos.w > 0.0) visibility = shadowTest(shadowMap, lPos.xyz / lPos.w, shadowsBias, smSize);
// Blend cascade
// https://github.com/TheRealMJP/Shadows
const float blendThres = 0.15;
float nextSplit = casData[c * 4][casi];
float splitSize = casi == 0 ? nextSplit : nextSplit - casData[c * 4][casi - 1];
float splitDist = (nextSplit - d) / splitSize;
if (splitDist <= blendThres && casi != c - 1) {
int casIndex2 = casIndex + 4;
mat4 LWVP2 = mat4(
casData[casIndex2 + 0],
casData[casIndex2 + 1],
casData[casIndex2 + 2],
casData[casIndex2 + 3]);
vec4 lPos2 = LWVP2 * vec4(p, 1.0);
float visibility2 = 1.0;
if (lPos2.w > 0.0) visibility2 = shadowTest(shadowMap, lPos2.xyz / lPos2.w, shadowsBias, smSize);
float lerpAmt = smoothstep(0.0, blendThres, splitDist);
return mix(visibility2, visibility, lerpAmt);
}
return visibility;
// Visualize cascades
// if (ci == 0) albedo.rgb = vec3(1.0, 0.0, 0.0);
// if (ci == 4) albedo.rgb = vec3(0.0, 1.0, 0.0);
// if (ci == 8) albedo.rgb = vec3(0.0, 0.0, 1.0);
// if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0);
}
// arm_dev
float shadowTestCascade(sampler2DShadow shadowMap, const vec3 eye, const vec3 p, const float shadowsBias, const vec2 smSize) {
const int c = shadowmapCascades;
float d = distance(eye, p);

View file

@ -20,6 +20,10 @@ void main() {
// Velocity is assumed to be calculated for motion blur, so we need to inverse it for reprojection
vec2 velocity = -textureLod(sveloc, texCoord, 0.0).rg;
#ifdef HLSL
velocity.y = -velocity.y;
#endif
// Reproject current coordinates and fetch previous pixel
vec4 previous = textureLod(tex2, texCoord + velocity, 0.0);

View file

@ -2,10 +2,6 @@ package armory.logicnode;
import iron.math.Vec4;
#if arm_physics
import haxebullet.Bullet;
#end
class CastPhysicsRayNode extends LogicNode {
var v = new Vec4();

View file

@ -11,8 +11,7 @@ class PlayActionNode extends LogicNode {
override function run(from:Int) {
var object:Object = inputs[1].get();
var action:String = inputs[2].get();
// TODO: assume input exists
var blendTime:Float = inputs.length > 3 ? inputs[3].get() : 0.2;
var blendTime:Float = inputs[3].get();
if (object == null) return;
var animation = object.animation;

View file

@ -172,7 +172,7 @@ class Inc {
// Resize shadow map
var l = path.light;
if (l.data.raw.type == "sun" && l.data.raw.shadowmap_size != config.rp_shadowmap_cascade) {
l.data.raw.shadowmap_size = config.rp_shadowmap;
l.data.raw.shadowmap_size = config.rp_shadowmap_cascade;
var rt = path.renderTargets.get("shadowMap");
if (rt != null) {
rt.unload();
@ -180,7 +180,8 @@ class Inc {
}
}
else if (l.data.raw.shadowmap_size != config.rp_shadowmap_cube) {
rt = path.renderTargets.get("shadowMapCube");
l.data.raw.shadowmap_size = config.rp_shadowmap_cube;
var rt = path.renderTargets.get("shadowMapCube");
if (rt != null) {
rt.unload();
path.renderTargets.remove("shadowMapCube");

View file

@ -480,19 +480,15 @@ class RenderPathDeferred {
#if rp_decals
{
#if arm_dev
path.setDepthFrom("gbuffer0", "gbuffer1"); // Unbind depth so we can read it
path.depthToRenderTarget.set("main", path.renderTargets.get("tex"));
path.setTarget("gbuffer0", ["gbuffer1"]);
#end
path.bindTarget("_main", "gbufferD");
path.drawDecals("decal");
#if arm_dev
path.setDepthFrom("gbuffer0", "tex"); // Re-bind depth
path.depthToRenderTarget.set("main", path.renderTargets.get("gbuffer0"));
#end
}
#end
@ -679,7 +675,6 @@ class RenderPathDeferred {
path.drawShader("shader_datas/deferred_light/deferred_light_VoxelAOvar") :
path.drawShader("shader_datas/deferred_light/deferred_light");
#end
path.setDepthFrom("tex", "gbuffer0"); // Re-bind depth
#if rp_probes
if (!path.isProbe) {
@ -689,6 +684,7 @@ class RenderPathDeferred {
if (!p.visible || p.culled) continue;
path.currentProbeIndex = i;
path.setTarget("tex");
path.bindTarget("_main", "gbufferD");
path.bindTarget("gbuffer0", "gbuffer0");
path.bindTarget("gbuffer1", "gbuffer1");
path.bindTarget(p.raw.name, "probeTex");
@ -702,6 +698,8 @@ class RenderPathDeferred {
}
#end
path.setDepthFrom("tex", "gbuffer0"); // Re-bind depth
// #if rp_volumetriclight
// {
// path.setTarget("bufvola");

View file

@ -62,7 +62,7 @@ class RenderPathRaytracer {
structure.add("nor", VertexData.Float3);
var geom = iron.Scene.active.meshes[0].data.geom;
var vb = new VertexBuffer(Std.int(geom.positions.length / 3), structure, kha.graphics5.Usage.StaticUsage);
var vb = new VertexBuffer(Std.int(geom.positions.length / 4), structure, kha.graphics5.Usage.StaticUsage);
var vba = vb.lock();
iron.data.Geometry.buildVertices(vba, geom.positions, geom.normals);
vb.unlock();

View file

@ -141,16 +141,16 @@ class Cycles {
if (frag.wposition) {
vert.add_uniform('mat4 W', '_worldMatrix');
vert.add_out('vec3 wposition');
vert.write_attrib('wposition = vec4(W * vec4(pos, 1.0)).xyz;');
vert.write_attrib('wposition = vec4(W * vec4(pos.xyz, 1.0)).xyz;');
}
else if (vert.wposition) {
vert.add_uniform('mat4 W', '_worldMatrix');
vert.write_attrib('vec3 wposition = vec4(W * vec4(pos, 1.0)).xyz;');
vert.write_attrib('vec3 wposition = vec4(W * vec4(pos.xyz, 1.0)).xyz;');
}
if (frag.vposition) {
vert.add_uniform('mat4 WV', '_worldViewMatrix');
vert.add_out('vec3 vposition');
vert.write_attrib('vposition = vec4(WV * vec4(pos, 1.0)).xyz;');
vert.write_attrib('vposition = vec4(WV * vec4(pos.xyz, 1.0)).xyz;');
}
if (frag.mposition) {
vert.add_out('vec3 mposition');
@ -162,7 +162,7 @@ class Cycles {
}
}
if (frag.wtangent) {
con.add_elem('tang', 3);
con.add_elem('tang', 'short4norm');
vert.add_uniform('mat3 N', '_normalMatrix');
vert.add_out('vec3 wtangent');
vert.write_attrib('wtangent = normalize(N * tang);');
@ -170,7 +170,7 @@ class Cycles {
if (frag.vVecCam) {
vert.add_uniform('mat4 WV', '_worldViewMatrix');
vert.add_out('vec3 eyeDirCam');
vert.write_attrib('eyeDirCam = vec4(WV * vec4(pos, 1.0)).xyz; eyeDirCam.z *= -1.0;');
vert.write_attrib('eyeDirCam = vec4(WV * vec4(pos.xyz, 1.0)).xyz; eyeDirCam.z *= -1.0;');
frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);');
}
if (frag.vVec) {
@ -437,12 +437,12 @@ class Cycles {
if (node.type == 'ATTRIBUTE') {
if (socket == node.outputs[0]) { // Color
curshader.context.add_elem('col', 3); // Vcols only for now
curshader.context.add_elem('col', 'short4norm'); // Vcols only for now
// return 'vcolor';
return 'vec3(0.0)';
}
else { // Vector
curshader.context.add_elem('tex', 2); // UVMaps only for now
curshader.context.add_elem('tex', 'short2norm'); // UVMaps only for now
// mat = mat_get_material()
// mat_users = mat_get_material_users()
// if mat_users != None and mat in mat_users:
@ -451,7 +451,7 @@ class Cycles {
// lays = mat_user.data.uv_layers
// # Second uvmap referenced
// if len(lays) > 1 and node.attribute_name == lays[1].name:
// con.add_elem('tex1', 2)
// con.add_elem('tex1', 'short2norm')
// return 'vec3(texCoord1.x, 1.0 - texCoord1.y, 0.0)'
return 'vec3(texCoord.x, 1.0 - texCoord.y, 0.0)';
}
@ -932,7 +932,7 @@ class Cycles {
return 'n';
}
else if (socket == node.outputs[2]) {// UV
curshader.context.add_elem('tex', 2);
curshader.context.add_elem('tex', 'short2norm');
return 'vec3(texCoord.x, 1.0 - texCoord.y, 0.0)';
}
else if (socket == node.outputs[3]) { // Object
@ -954,7 +954,7 @@ class Cycles {
else if (node.type == 'UVMAP') {
//dupli = node.from_dupli
curshader.context.add_elem('tex', 2);
curshader.context.add_elem('tex', 'short2norm');
return 'vec3(texCoord.x, 1.0 - texCoord.y, 0.0)';
}
@ -1127,7 +1127,7 @@ class Cycles {
// if (strength != '1.0') frag.write('n.xy *= $strength;');
// # frag.write('n = normalize(TBN * normalize(n));')
// frag.write('n = TBN * normalize(n);')
// con.add_elem('tang', 3)
// con.add_elem('tang', 'short4norm')
parse_teximage_vector = true;
frag.write_normal--;
@ -1716,7 +1716,7 @@ class Cycles {
public static var texCoordName = 'texCoord';
static function texture_store(node:TNode, tex:TBindTexture, tex_name:String, to_linear = false):String {
matcon.bind_textures.push(tex);
curshader.context.add_elem('tex', 2);
curshader.context.add_elem('tex', 'short2norm');
curshader.add_uniform('sampler2D $tex_name');
var uv_name = '';
if (getInputLink(node.inputs[0]) != null && parse_teximage_vector) {

View file

@ -41,7 +41,7 @@ class CyclesShaderContext {
alpha_blend_operation: props.alpha_blend_operation,
fragment_shader: '',
vertex_shader: '',
vertex_structure: Reflect.hasField(props, 'vertex_structure') ? props.vertex_structure : [ {name: "pos", size: 3}, {name: "nor", size: 3}]
vertex_elements: Reflect.hasField(props, 'vertex_elements') ? props.vertex_elements : [ {name: "pos", data: 'short4norm'}, {name: "nor", data: 'short2norm'}]
};
if (props.color_write_red != null)
@ -65,23 +65,23 @@ class CyclesShaderContext {
constants = data.constants = [];
}
public function add_elem(name:String, size:Int) {
for (e in data.vertex_structure) {
public function add_elem(name:String, data:String) {
for (e in data.vertex_elements) {
if (e.name == name) return;
}
var elem:TVertexData = { name: name, size: size };
data.vertex_structure.push(elem);
var elem:TVertexElement = { name: name, data: data };
data.vertex_elements.push(elem);
}
public function is_elem(name:String) {
for (elem in data.vertex_structure)
for (elem in data.vertex_elements)
if (elem.name == name)
return true;
return false;
}
public function get_elem(name:String):TVertexData {
for (elem in data.vertex_structure) {
public function get_elem(name:String):TVertexElement {
for (elem in data.vertex_elements) {
#if cpp
if (Reflect.field(elem, "name") == name)
#else
@ -259,7 +259,7 @@ class CyclesShader {
function vstruct_to_vsin() {
// if self.shader_type != 'vert' or self.ins != [] or not self.vstruct_as_vsin: # Vertex structure as vertex shader input
// return
var vs = context.data.vertex_structure;
var vs = context.data.vertex_elements;
for (e in vs) {
add_in('vec' + e.size + ' ' + e.name);
}

View file

@ -30,17 +30,10 @@ class Starter {
armory.object.Uniforms.register();
var windowMode = c.window_mode == 0 ? kha.WindowMode.Windowed : kha.WindowMode.Fullscreen;
#if arm_dev
var windowFeatures = None;
if (c.window_resizable) windowFeatures |= FeatureResizable;
if (c.window_maximizable) windowFeatures |= FeatureMaximizable;
if (c.window_minimizable) windowFeatures |= FeatureMinimizable;
#else
var windowFeatures = 0;
if (c.window_resizable) windowFeatures |= WindowOptions.FeatureResizable;
if (c.window_maximizable) windowFeatures |= WindowOptions.FeatureMaximizable;
if (c.window_minimizable) windowFeatures |= WindowOptions.FeatureMinimizable;
#end
kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window:kha.Window) {

View file

@ -504,7 +504,7 @@ class ConvexBreaker {
na.push(normal.x);
na.push(normal.y);
na.push(normal.z);
ind.push(Std.int(pa.length / 3 - 1));
ind.push(Std.int(pa.length / 4 - 1));
}
else {
na[fi * 3] = normal.x;
@ -530,13 +530,13 @@ class ConvexBreaker {
var pos:TVertexArray = {
attrib: "pos",
size: 3,
size: 4,
values: paa
};
var nor:TVertexArray = {
attrib: "nor",
size: 3,
size: 2,
values: naa
};

View file

@ -7,9 +7,6 @@ import iron.math.Mat4;
import iron.math.RayCaster;
import armory.trait.physics.RigidBody;
import armory.trait.physics.PhysicsWorld;
#if arm_bullet
import haxebullet.Bullet;
#end
class PhysicsDrag extends Trait {
@ -17,12 +14,12 @@ class PhysicsDrag extends Trait {
public function new() { super(); }
#else
var pickConstraint:BtGeneric6DofConstraintPointer = null;
var pickConstraint:bullet.Bt.Generic6DofConstraint = null;
var pickDist:Float;
var pickedBody:RigidBody = null;
var rayFrom:BtVector3;
var rayTo:BtVector3;
var rayFrom:bullet.Bt.Vector3;
var rayTo:bullet.Bt.Vector3;
static var v = new Vec4();
static var m = Mat4.identity();
@ -53,16 +50,16 @@ class PhysicsDrag extends Trait {
var hit = physics.hitPointWorld;
v.setFrom(hit);
v.applymat4(m);
var localPivot = BtVector3.create(v.x, v.y, v.z);
var tr = BtTransform.create();
var localPivot = new bullet.Bt.Vector3(v.x, v.y, v.z);
var tr = new bullet.Bt.Transform();
tr.setIdentity();
tr.setOrigin(localPivot);
pickConstraint = BtGeneric6DofConstraint.create(b.body, tr, false);
pickConstraint.setLinearLowerLimit(BtVector3.create(0, 0, 0));
pickConstraint.setLinearUpperLimit(BtVector3.create(0, 0, 0));
pickConstraint.setAngularLowerLimit(BtVector3.create(-10, -10, -10));
pickConstraint.setAngularUpperLimit(BtVector3.create(10, 10, 10));
pickConstraint = new bullet.Bt.Generic6DofConstraint(b.body, tr, false);
pickConstraint.setLinearLowerLimit(new bullet.Bt.Vector3(0, 0, 0));
pickConstraint.setLinearUpperLimit(new bullet.Bt.Vector3(0, 0, 0));
pickConstraint.setAngularLowerLimit(new bullet.Bt.Vector3(-10, -10, -10));
pickConstraint.setAngularUpperLimit(new bullet.Bt.Vector3(10, 10, 10));
physics.world.addConstraint(pickConstraint, false);
/*pickConstraint.setParam(4, 0.8, 0);
@ -99,12 +96,12 @@ class PhysicsDrag extends Trait {
setRays();
// Keep it at the same picking distance
var dir = BtVector3.create(rayTo.x() - rayFrom.x(), rayTo.y() - rayFrom.y(), rayTo.z() - rayFrom.z());
var dir = new bullet.Bt.Vector3(rayTo.x() - rayFrom.x(), rayTo.y() - rayFrom.y(), rayTo.z() - rayFrom.z());
dir.normalize();
dir.setX(dir.x() * pickDist);
dir.setY(dir.y() * pickDist);
dir.setZ(dir.z() * pickDist);
var newPivotB = BtVector3.create(rayFrom.x() + dir.x(), rayFrom.y() + dir.y(), rayFrom.z() + dir.z());
var newPivotB = new bullet.Bt.Vector3(rayFrom.x() + dir.x(), rayFrom.y() + dir.y(), rayFrom.z() + dir.z());
#if js
pickConstraint.getFrameOffsetA().setOrigin(newPivotB);
@ -121,9 +118,9 @@ class PhysicsDrag extends Trait {
var mouse = Input.getMouse();
var camera = iron.Scene.active.camera;
var v = camera.transform.world.getLoc();
rayFrom = BtVector3.create(v.x, v.y, v.z);
rayFrom = new bullet.Bt.Vector3(v.x, v.y, v.z);
RayCaster.getDirection(start, end, mouse.x, mouse.y, camera);
rayTo = BtVector3.create(end.x, end.y, end.z);
rayTo = new bullet.Bt.Vector3(end.x, end.y, end.z);
}
#end
}

View file

@ -6,9 +6,6 @@ import iron.object.CameraObject;
import iron.object.Transform;
import iron.system.Time;
import armory.trait.physics.PhysicsWorld;
#if arm_bullet
import haxebullet.Bullet;
#end
class VehicleBody extends Trait {
@ -26,8 +23,8 @@ class VehicleBody extends Trait {
var camera:CameraObject;
var wheels:Array<Object> = [];
var vehicle:BtRaycastVehiclePointer = null;
var carChassis:BtRigidBodyPointer;
var vehicle:bullet.Bt.RaycastVehicle = null;
var carChassis:bullet.Bt.RigidBody;
var chassis_mass = 600.0;
var wheelFriction = 1000;
@ -58,31 +55,31 @@ class VehicleBody extends Trait {
wheels.push(iron.Scene.active.root.getChild(n));
}
var wheelDirectionCS0 = BtVector3.create(0, 0, -1);
var wheelAxleCS = BtVector3.create(1, 0, 0);
var wheelDirectionCS0 = new bullet.Bt.Vector3(0, 0, -1);
var wheelAxleCS = new bullet.Bt.Vector3(1, 0, 0);
var chassisShape = BtBoxShape.create(BtVector3.create(
var chassisShape = new bullet.Bt.BoxShape(new bullet.Bt.Vector3(
transform.dim.x / 2,
transform.dim.y / 2,
transform.dim.z / 2));
var compound = BtCompoundShape.create();
var compound = new bullet.Bt.CompoundShape();
var localTrans = BtTransform.create();
var localTrans = new bullet.Bt.Transform();
localTrans.setIdentity();
localTrans.setOrigin(BtVector3.create(0, 0, 1));
localTrans.setOrigin(new bullet.Bt.Vector3(0, 0, 1));
compound.addChildShape(localTrans, chassisShape);
carChassis = createRigidBody(chassis_mass, compound);
// Create vehicle
var tuning = BtVehicleTuning.create();
var vehicleRayCaster = BtDefaultVehicleRaycaster.create(physics.world);
vehicle = BtRaycastVehicle.create(tuning, carChassis, vehicleRayCaster);
var tuning = new bullet.Bt.VehicleTuning();
var vehicleRayCaster = new bullet.Bt.DefaultVehicleRaycaster(physics.world);
vehicle = new bullet.Bt.RaycastVehicle(tuning, carChassis, vehicleRayCaster);
// Never deactivate the vehicle
carChassis.setActivationState(BtCollisionObject.DISABLE_DEACTIVATION);
carChassis.setActivationState(bullet.Bt.CollisionObject.DISABLE_DEACTIVATION);
// Choose coordinate system
var rightIndex = 0;
@ -189,32 +186,32 @@ class VehicleBody extends Trait {
camera.buildMatrix();
}
function createRigidBody(mass:Float, shape:BtCompoundShapePointer):BtRigidBodyPointer {
function createRigidBody(mass:Float, shape:bullet.Bt.CompoundShape):bullet.Bt.RigidBody {
var localInertia = BtVector3.create(0, 0, 0);
var localInertia = new bullet.Bt.Vector3(0, 0, 0);
shape.calculateLocalInertia(mass, localInertia);
var centerOfMassOffset = BtTransform.create();
var centerOfMassOffset = new bullet.Bt.Transform();
centerOfMassOffset.setIdentity();
var startTransform = BtTransform.create();
var startTransform = new bullet.Bt.Transform();
startTransform.setIdentity();
startTransform.setOrigin(BtVector3.create(
startTransform.setOrigin(new bullet.Bt.Vector3(
transform.loc.x,
transform.loc.y,
transform.loc.z));
startTransform.setRotation(BtQuaternion.create(
startTransform.setRotation(new bullet.Bt.Quaternion(
transform.rot.x,
transform.rot.y,
transform.rot.z,
transform.rot.w));
var myMotionState = BtDefaultMotionState.create(startTransform, centerOfMassOffset);
var cInfo = BtRigidBodyConstructionInfo.create(mass, myMotionState, shape, localInertia);
var myMotionState = new bullet.Bt.DefaultMotionState(startTransform, centerOfMassOffset);
var cInfo = new bullet.Bt.RigidBodyConstructionInfo(mass, myMotionState, shape, localInertia);
var body = BtRigidBody.create(cInfo);
body.setLinearVelocity(BtVector3.create(0, 0, 0));
body.setAngularVelocity(BtVector3.create(0, 0, 0));
var body = new bullet.Bt.RigidBody(cInfo);
body.setLinearVelocity(new bullet.Bt.Vector3(0, 0, 0));
body.setAngularVelocity(new bullet.Bt.Vector3(0, 0, 0));
physics.world.addRigidBody(body);
return body;
@ -261,8 +258,8 @@ class VehicleWheel {
locZ = vehicleTransform.dim.z / 2 + transform.loc.z;
}
public function getConnectionPoint():BtVector3 {
return BtVector3.create(locX, locY, locZ);
public function getConnectionPoint():bullet.Bt.Vector3 {
return new bullet.Bt.Vector3(locX, locY, locZ);
}
#end
}

View file

@ -198,6 +198,7 @@ class DebugConsole extends Trait {
var loc = selectedObject.transform.loc;
var scale = selectedObject.transform.scale;
var rot = selectedObject.transform.rot.getEuler();
var dim = selectedObject.transform.dim;
rot.mult(180 / 3.141592);
var f = 0.0;
@ -266,6 +267,24 @@ class DebugConsole extends Trait {
f = Std.parseFloat(ui.textInput(h, "Z"));
if (ui.changed) scale.z = f;
ui.row(row4);
ui.text("Dimensions");
h = Id.handle();
h.text = Math.roundfp(dim.x) + "";
f = Std.parseFloat(ui.textInput(h, "X"));
if (ui.changed) dim.x = f;
h = Id.handle();
h.text = Math.roundfp(dim.y) + "";
f = Std.parseFloat(ui.textInput(h, "Y"));
if (ui.changed) dim.y = f;
h = Id.handle();
h.text = Math.roundfp(dim.z) + "";
f = Std.parseFloat(ui.textInput(h, "Z"));
if (ui.changed) dim.z = f;
selectedObject.transform.dirty = true;
if (selectedObject.traits.length > 0) {

View file

@ -2,7 +2,6 @@ package armory.trait.physics.bullet;
#if arm_bullet
import haxebullet.Bullet;
import iron.Trait;
import iron.math.Vec4;
import iron.math.Quat;
@ -12,8 +11,8 @@ import iron.object.MeshObject;
class KinematicCharacterController extends Trait {
var shape:ControllerShape;
var shapeConvex:BtConvexShapePointer;
var shapeConvexHull:BtConvexHullShapePointer;
var shapeConvex:bullet.Bt.ConvexShape;
var shapeConvexHull:bullet.Bt.ConvexHullShape;
var isConvexHull = false;
public var physics:PhysicsWorld;
@ -32,17 +31,17 @@ class KinematicCharacterController extends Trait {
var currentScaleZ:Float;
var jumpSpeed:Float;
public var body:BtPairCachingGhostObjectPointer = null;
public var character:BtKinematicCharacterControllerPointer = null;
public var body:bullet.Bt.PairCachingGhostObject = null;
public var character:bullet.Bt.KinematicCharacterController = null;
public var ready = false;
static var nextId = 0;
public var id = 0;
public var onReady:Void->Void = null;
static var nullvec = true;
static var vec1:BtVector3;
static var quat1:BtQuaternion;
static var trans1:BtTransform;
static var vec1:bullet.Bt.Vector3;
static var quat1:bullet.Bt.Quaternion;
static var trans1:bullet.Bt.Transform;
static var quat = new Quat();
public function new(mass = 1.0, shape = ControllerShape.Capsule, jumpSpeed = 8.0, friction = 0.5, restitution = 0.0,
@ -51,9 +50,9 @@ class KinematicCharacterController extends Trait {
if (nullvec) {
nullvec = false;
vec1 = BtVector3.create(0, 0, 0);
quat1 = BtQuaternion.create(0, 0, 0, 0);
trans1 = BtTransform.create();
vec1 = new bullet.Bt.Vector3(0, 0, 0);
quat1 = new bullet.Bt.Quaternion(0, 0, 0, 0);
trans1 = new bullet.Bt.Transform();
}
this.mass = mass;
@ -94,21 +93,21 @@ class KinematicCharacterController extends Trait {
vec1.setX(withMargin(transform.dim.x / 2));
vec1.setY(withMargin(transform.dim.y / 2));
vec1.setZ(withMargin(transform.dim.z / 2));
shapeConvex = BtBoxShape.create(vec1);
shapeConvex = new bullet.Bt.BoxShape(vec1);
}
else if (shape == ControllerShape.Sphere) {
var width = transform.dim.x;
if(transform.dim.y > width) width = transform.dim.y;
if(transform.dim.z > width) width = transform.dim.z;
shapeConvex = BtSphereShape.create(withMargin(width / 2));
shapeConvex = new bullet.Bt.SphereShape(withMargin(width / 2));
}
else if (shape == ControllerShape.ConvexHull && mass > 0) {
shapeConvexHull = BtConvexHullShape.create();
shapeConvexHull = new bullet.Bt.ConvexHullShape();
isConvexHull = true;
addPointsToConvexHull(shapeConvexHull, transform.scale, collisionMargin);
}
else if (shape == ControllerShape.Cone) {
shapeConvex = BtConeShapeZ.create(
shapeConvex = new bullet.Bt.ConeShapeZ(
withMargin(transform.dim.x / 2), // Radius
withMargin(transform.dim.z)); // Height
}
@ -116,11 +115,11 @@ class KinematicCharacterController extends Trait {
vec1.setX(withMargin(transform.dim.x / 2));
vec1.setY(withMargin(transform.dim.y / 2));
vec1.setZ(withMargin(transform.dim.z / 2));
shapeConvex = BtCylinderShapeZ.create(vec1);
shapeConvex = new bullet.Bt.CylinderShapeZ(vec1);
}
else if (shape == ControllerShape.Capsule) {
var r = transform.dim.x / 2;
shapeConvex = BtCapsuleShapeZ.create(
shapeConvex = new bullet.Bt.CapsuleShapeZ(
withMargin(r), // Radius
withMargin(transform.dim.z - r * 2)); // Height between 2 sphere centers
}
@ -138,17 +137,17 @@ class KinematicCharacterController extends Trait {
quat1.setW(quat.w);
trans1.setRotation(quat1);
body = BtPairCachingGhostObject.create();
body = new bullet.Bt.PairCachingGhostObject();
body.setCollisionShape(isConvexHull ? shapeConvexHull : shapeConvex);
body.setCollisionFlags(BtCollisionObject.CF_CHARACTER_OBJECT);
body.setCollisionFlags(bullet.Bt.CollisionObject.CF_CHARACTER_OBJECT);
body.setWorldTransform(trans1);
body.setFriction(friction);
body.setRollingFriction(friction);
body.setRestitution(restitution);
#if js
character = BtKinematicCharacterController.create(body, isConvexHull ? shapeConvexHull : shapeConvex, 0.5, 2);
character = new bullet.Bt.KinematicCharacterController(body, isConvexHull ? shapeConvexHull : shapeConvex, 0.5, 2);
#elseif cpp
character = BtKinematicCharacterController.create(body, isConvexHull ? shapeConvexHull : shapeConvex, 0.5, BtVector3.create(0.0, 0.0, 1.0));
character = new bullet.Bt.KinematicCharacterController.create(body, isConvexHull ? shapeConvexHull : shapeConvex, 0.5, bullet.Bt.Vector3(0.0, 0.0, 1.0));
#end
character.setJumpSpeed(jumpSpeed);
character.setUseGhostSweepTest(true);
@ -168,7 +167,7 @@ class KinematicCharacterController extends Trait {
body.setUserIndex(id);
#end
physics.addKinematicCharacterController(this);
// physics.addKinematicCharacterController(this);
if (onReady != null) onReady();
}
@ -247,7 +246,7 @@ class KinematicCharacterController extends Trait {
#end
public function removeFromWorld() {
if (physics != null) physics.removeKinematicCharacterController(this);
// if (physics != null) physics.removeKinematicCharacterController(this);
}
public function activate() {
@ -329,14 +328,14 @@ class KinematicCharacterController extends Trait {
physics.world.updateSingleAabb(body);
}
function addPointsToConvexHull(shape:BtConvexHullShapePointer, scale:Vec4, margin:Float) {
function addPointsToConvexHull(shape:bullet.Bt.ConvexHullShape, scale:Vec4, margin:Float) {
var positions = cast(object, MeshObject).data.geom.positions;
var sx = scale.x * (1.0 - margin);
var sy = scale.y * (1.0 - margin);
var sz = scale.z * (1.0 - margin);
for (i in 0...Std.int(positions.length / 3)) {
for (i in 0...Std.int(positions.length / 4)) {
vec1.setX(positions[i * 3] * sx);
vec1.setY(positions[i * 3 + 1] * sy);
vec1.setZ(positions[i * 3 + 2] * sz);

View file

@ -4,7 +4,6 @@ package armory.trait.physics.bullet;
import armory.trait.physics.RigidBody;
import armory.trait.physics.PhysicsWorld;
import haxebullet.Bullet;
class PhysicsConstraint extends iron.Trait {
@ -14,25 +13,25 @@ class PhysicsConstraint extends iron.Trait {
var disableCollisions:Bool;
var breakingThreshold:Float;
var limits:Array<Float>;
var con:BtTypedConstraintPointer = null;
var con:bullet.Bt.TypedConstraint = null;
static var nullvec = true;
static var vec1:BtVector3;
static var vec2:BtVector3;
static var vec3:BtVector3;
static var trans1:BtTransform;
static var trans2:BtTransform;
static var vec1:bullet.Bt.Vector3;
static var vec2:bullet.Bt.Vector3;
static var vec3:bullet.Bt.Vector3;
static var trans1:bullet.Bt.Transform;
static var trans2:bullet.Bt.Transform;
public function new(body1:String, body2:String, type:String, disableCollisions:Bool, breakingThreshold:Float, limits:Array<Float> = null) {
super();
if (nullvec) {
nullvec = false;
vec1 = BtVector3.create(0, 0, 0);
vec2 = BtVector3.create(0, 0, 0);
vec3 = BtVector3.create(0, 0, 0);
trans1 = BtTransform.create();
trans2 = BtTransform.create();
vec1 = new bullet.Bt.Vector3(0, 0, 0);
vec2 = new bullet.Bt.Vector3(0, 0, 0);
vec3 = new bullet.Bt.Vector3(0, 0, 0);
trans1 = new bullet.Bt.Transform();
trans2 = new bullet.Bt.Transform();
}
this.body1 = body1;
@ -70,7 +69,7 @@ class PhysicsConstraint extends iron.Trait {
trans2.setOrigin(vec2);
if (type == "GENERIC" || type == "FIXED" || type == "POINT") {
var c = BtGeneric6DofConstraint.create2(rb1.body, rb2.body, trans1, trans2, false);
var c = bullet.Bt.Generic6DofConstraint.new2(rb1.body, rb2.body, trans1, trans2, false);
if (type == "POINT") {
vec1.setX(0);
vec1.setY(0);
@ -113,7 +112,7 @@ class PhysicsConstraint extends iron.Trait {
axis.setX(0);
axis.setY(0);
axis.setZ(1);
var c = BtHingeConstraint.create(rb1.body, rb2.body, vec2, vec1, axis, axis);
var c = new bullet.Bt.HingeConstraint(rb1.body, rb2.body, vec2, vec1, axis, axis);
con = cast c;
}
// else if (type == "SLIDER") {}
@ -128,7 +127,7 @@ class PhysicsConstraint extends iron.Trait {
public function removeFromWorld() {
#if js
Ammo.destroy(con);
bullet.Bt.Ammo.destroy(con);
#end
}
}

View file

@ -13,7 +13,6 @@ import iron.data.MeshData;
import iron.data.SceneFormat;
import armory.trait.physics.RigidBody;
import armory.trait.physics.PhysicsWorld;
import haxebullet.Bullet;
class PhysicsHook extends Trait {
var target:Object;
@ -21,17 +20,17 @@ class PhysicsHook extends Trait {
var targetTransform:Transform;
var verts:Array<Float>;
var constraint:BtGeneric6DofConstraintPointer = null;
var constraint:bullet.Bt.Generic6DofConstraint = null;
#if arm_physics_soft
var hookRB:BtRigidBodyPointer = null;
var hookRB:bullet.Bt.RigidBody = null;
#end
static var nullvec = true;
static var vec1:BtVector3;
static var quat1:BtQuaternion;
static var trans1:BtTransform;
static var trans2:BtTransform;
static var vec1:bullet.Bt.Vector3;
static var quat1:bullet.Bt.Quaternion;
static var trans1:bullet.Bt.Transform;
static var trans2:bullet.Bt.Transform;
static var quat = new Quat();
public function new(targetName:String, verts:Array<Float>) {
@ -39,10 +38,10 @@ class PhysicsHook extends Trait {
if (nullvec) {
nullvec = false;
vec1 = BtVector3.create(0, 0, 0);
quat1 = BtQuaternion.create(0, 0, 0, 0);
trans1 = BtTransform.create();
trans2 = BtTransform.create();
vec1 = new bullet.Bt.Vector3(0, 0, 0);
quat1 = new bullet.Bt.Quaternion(0, 0, 0, 0);
trans1 = new bullet.Bt.Transform();
trans2 = new bullet.Bt.Transform();
}
this.targetName = targetName;
@ -80,15 +79,15 @@ class PhysicsHook extends Trait {
var centerOfMassOffset = trans2;
centerOfMassOffset.setIdentity();
var mass = 0.0;
var motionState = BtDefaultMotionState.create(trans1, centerOfMassOffset);
var motionState = new bullet.Bt.DefaultMotionState(trans1, centerOfMassOffset);
var inertia = vec1;
inertia.setX(0);
inertia.setY(0);
inertia.setZ(0);
var shape = BtSphereShape.create(0.01);
var shape = new bullet.Bt.SphereShape(0.01);
shape.calculateLocalInertia(mass, inertia);
var bodyCI = BtRigidBodyConstructionInfo.create(mass, motionState, shape, inertia);
hookRB = BtRigidBody.create(bodyCI);
var bodyCI = new bullet.Bt.RigidBodyConstructionInfo(mass, motionState, shape, inertia);
hookRB = new bullet.Bt.RigidBody(bodyCI);
#if js
var nodes = sb.body.get_m_nodes();
@ -97,7 +96,7 @@ class PhysicsHook extends Trait {
#end
var geom = cast(object, MeshObject).data.geom;
var numNodes = Std.int(geom.positions.length / 3);
var numNodes = Std.int(geom.positions.length / 4);
for (i in 0...numNodes) {
var node = nodes.at(i);
#if js
@ -131,7 +130,7 @@ class PhysicsHook extends Trait {
vec1.setY(targetTransform.worldy() - object.transform.worldy());
vec1.setZ(targetTransform.worldz() - object.transform.worldz());
trans1.setOrigin(vec1);
constraint = BtGeneric6DofConstraint.create(rb1.body, trans1, false);
constraint = new bullet.Bt.Generic6DofConstraint(rb1.body, trans1, false);
vec1.setX(0);
vec1.setY(0);
vec1.setZ(0);

View file

@ -2,7 +2,6 @@ package armory.trait.physics.bullet;
#if arm_bullet
import haxebullet.Bullet;
import iron.Trait;
import iron.system.Time;
import iron.math.Vec4;
@ -28,12 +27,12 @@ class PhysicsWorld extends Trait {
static var sceneRemoved = false;
#if arm_physics_soft
public var world:BtSoftRigidDynamicsWorldPointer;
public var world:bullet.Bt.SoftRigidDynamicsWorld;
#else
public var world:BtDiscreteDynamicsWorldPointer;
public var world:bullet.Bt.DiscreteDynamicsWorld;
#end
var dispatcher:BtCollisionDispatcherPointer;
var dispatcher:bullet.Bt.CollisionDispatcher;
var gimpactRegistered = false;
var contacts:Array<ContactPair>;
var preUpdates:Array<Void->Void> = null;
@ -47,8 +46,8 @@ class PhysicsWorld extends Trait {
var pairCache:Bool = false;
static var nullvec = true;
static var vec1:BtVector3;
static var vec2:BtVector3;
var vec1:bullet.Bt.Vector3 = null;
var vec2:bullet.Bt.Vector3 = null;
#if arm_debug
public static var physTime = 0.0;
@ -59,8 +58,8 @@ class PhysicsWorld extends Trait {
if (nullvec) {
nullvec = false;
vec1 = BtVector3.create(0, 0, 0);
vec2 = BtVector3.create(0, 0, 0);
vec1 = new bullet.Bt.Vector3(0, 0, 0);
vec2 = new bullet.Bt.Vector3(0, 0, 0);
}
// Scene spawn
@ -101,47 +100,49 @@ class PhysicsWorld extends Trait {
}
function createPhysics() {
var broadphase = BtDbvtBroadphase.create();
var broadphase = new bullet.Bt.DbvtBroadphase();
#if arm_physics_soft
var collisionConfiguration = BtSoftBodyRigidBodyCollisionConfiguration.create();
var collisionConfiguration = new bullet.Bt.SoftBodyRigidBodyCollisionConfiguration();
#else
var collisionConfiguration = BtDefaultCollisionConfiguration.create();
var collisionConfiguration = new bullet.Bt.DefaultCollisionConfiguration();
#end
dispatcher = BtCollisionDispatcher.create(collisionConfiguration);
var solver = BtSequentialImpulseConstraintSolver.create();
dispatcher = new bullet.Bt.CollisionDispatcher(collisionConfiguration);
var solver = new bullet.Bt.SequentialImpulseConstraintSolver();
var g = iron.Scene.active.raw.gravity;
var gravity = g == null ? new Vec4(0, 0, -9.81) : new Vec4(g[0], g[1], g[2]);
#if arm_physics_soft
var softSolver = BtDefaultSoftBodySolver.create();
world = BtSoftRigidDynamicsWorld.create(dispatcher, broadphase, solver, collisionConfiguration, softSolver);
var softSolver = new bullet.Bt.DefaultSoftBodySolver();
world = new bullet.Bt.SoftRigidDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration, softSolver);
vec1.setX(gravity.x);
vec1.setY(gravity.y);
vec1.setZ(gravity.z);
#if js
world.getWorldInfo().set_m_gravity(vec1);
#elseif cpp
#else
world.getWorldInfo().m_gravity = vec1;
#end
#else
world = BtDiscreteDynamicsWorld.create(dispatcher, broadphase, solver, collisionConfiguration);
world = new bullet.Bt.DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
#end
setGravity(gravity);
}
public function setGravity(v:Vec4) {
vec1.setX(v.x);
vec1.setY(v.y);
vec1.setZ(v.z);
vec1.setValue(v.x, v.y, v.z);
world.setGravity(vec1);
}
public function addRigidBody(body:RigidBody) {
#if js
world.addRigidBodyToGroup(body.body, body.group, body.group);
#else
world.addRigidBody(body.body, body.group, body.group);
#end
rbMap.set(body.id, body);
}
@ -151,36 +152,37 @@ class PhysicsWorld extends Trait {
if (world != null) world.removeRigidBody(body.body);
rbMap.remove(body.id);
#if js
Ammo.destroy(body.motionState);
Ammo.destroy(body.btshape);
Ammo.destroy(body.body);
#elseif cpp
var cbody = body.body;
untyped __cpp__("delete cbody");
bullet.Bt.Ammo.destroy(body.motionState);
bullet.Bt.Ammo.destroy(body.btshape);
bullet.Bt.Ammo.destroy(body.body);
#else
body.motionState.delete();
body.btshape.delete();
body.body.delete();
#end
}
public function addKinematicCharacterController(controller:KinematicCharacterController) {
if (!pairCache){ // Only create PairCache if needed
world.getPairCache().setInternalGhostPairCallback(BtGhostPairCallbackPointer.create());
pairCache = true;
}
world.addAction(controller.character);
world.addCollisionObjectToGroup(controller.body, controller.group, controller.group);
}
// public function addKinematicCharacterController(controller:KinematicCharacterController) {
// if (!pairCache){ // Only create PairCache if needed
// world.getPairCache().setInternalGhostPairCallback(BtGhostPairCallbackPointer.create());
// pairCache = true;
// }
// world.addAction(controller.character);
// world.addCollisionObjectToGroup(controller.body, controller.group, controller.group);
// }
public function removeKinematicCharacterController(controller:KinematicCharacterController) {
if (world != null) {
world.removeCollisionObject(controller.body);
world.removeAction(controller.character);
}
#if js
Ammo.destroy(controller.body);
#elseif cpp
var cbody = controller.body;
untyped __cpp__("delete cbody");
#end
}
// public function removeKinematicCharacterController(controller:KinematicCharacterController) {
// if (world != null) {
// world.removeCollisionObject(controller.body);
// world.removeAction(controller.character);
// }
// #if js
// bullet.Bt.Ammo.destroy(controller.body);
// #else
// var cbody = controller.body;
// untyped __cpp__("delete cbody");
// #end
// }
/**
* Used to get intersecting rigid bodies with the passed in RigidBody as reference. Often used when checking for object collisions.
@ -198,10 +200,11 @@ class PhysicsWorld extends Trait {
if (c.a == untyped body.body.userIndex) res.push(rbMap.get(c.b));
else if (c.b == untyped body.body.userIndex) res.push(rbMap.get(c.a));
#elseif cpp
#else
if (c.a == body.body.getUserIndex()) res.push(rbMap.get(c.b));
else if (c.b == body.body.getUserIndex()) res.push(rbMap.get(c.a));
var ob:bullet.Bt.CollisionObject = body.body;
if (c.a == ob.getUserIndex()) res.push(rbMap.get(c.b));
else if (c.b == ob.getUserIndex()) res.push(rbMap.get(c.a));
#end
}
@ -218,17 +221,18 @@ class PhysicsWorld extends Trait {
if (c.a == untyped body.body.userIndex) res.push(c);
else if (c.b == untyped body.body.userIndex) res.push(c);
#elseif cpp
#else
if (c.a == body.body.getUserIndex()) res.push(c);
else if (c.b == body.body.getUserIndex()) res.push(c);
var ob:bullet.Bt.CollisionObject = body.body;
if (c.a == ob.getUserIndex()) res.push(c);
else if (c.b == ob.getUserIndex()) res.push(c);
#end
}
return res;
}
public function lateUpdate() {
function lateUpdate() {
var t = Time.delta * timeScale;
if (t == 0.0) return; // Simulation paused
@ -251,29 +255,30 @@ class PhysicsWorld extends Trait {
function updateContacts() {
contacts = [];
var numManifolds = dispatcher.getNumManifolds();
var disp:bullet.Bt.Dispatcher = dispatcher;
var numManifolds = disp.getNumManifolds();
for (i in 0...numManifolds) {
var contactManifold = dispatcher.getManifoldByIndexInternal(i);
var contactManifold = disp.getManifoldByIndexInternal(i);
#if js
var obA = contactManifold.getBody0();
var obB = contactManifold.getBody1();
var bodyA = untyped Ammo.btRigidBody.prototype.upcast(obA);
var bodyB = untyped Ammo.btRigidBody.prototype.upcast(obB);
var cp = new ContactPair(untyped bodyA.userIndex, untyped bodyB.userIndex);
#elseif cpp
var cp = new ContactPair(contactManifold.getBody0().getUserIndex(), contactManifold.getBody1().getUserIndex());
var body0 = untyped bullet.Bt.Ammo.btRigidBody.prototype.upcast(contactManifold.getBody0());
var body1 = untyped bullet.Bt.Ammo.btRigidBody.prototype.upcast(contactManifold.getBody1());
var cp = new ContactPair(untyped body0.userIndex, untyped body1.userIndex);
#else
var body0:bullet.Bt.CollisionObject = contactManifold.getBody0();
var body1:bullet.Bt.CollisionObject = contactManifold.getBody1();
var cp = new ContactPair(body0.getUserIndex(), body1.getUserIndex());
#end
var numContacts = contactManifold.getNumContacts();
for (j in 0...numContacts) {
var pt:BtManifoldPoint = contactManifold.getContactPoint(j);
var pt:bullet.Bt.ManifoldPoint = contactManifold.getContactPoint(j);
if (pt.getDistance() < 0) {
#if js
var posA = pt.get_m_positionWorldOnA();
var posB = pt.get_m_positionWorldOnB();
var nor = pt.get_m_normalWorldOnB();
#elseif cpp
#else
var posA = pt.m_positionWorldOnA;
var posB = pt.m_positionWorldOnB;
var nor = pt.m_normalWorldOnB;
@ -300,21 +305,20 @@ class PhysicsWorld extends Trait {
public function rayCast(from:Vec4, to:Vec4):RigidBody {
var rayFrom = vec1;
var rayTo = vec2;
rayFrom.setX(from.x);
rayFrom.setY(from.y);
rayFrom.setZ(from.z);
rayTo.setX(to.x);
rayTo.setY(to.y);
rayTo.setZ(to.z);
rayFrom.setValue(from.x, from.y, from.z);
rayTo.setValue(to.x, to.y, to.z);
var rayCallback = ClosestRayResultCallback.create(rayFrom, rayTo);
world.rayTest(rayFrom, rayTo, rayCallback);
var rayCallback = new bullet.Bt.ClosestRayResultCallback(rayFrom, rayTo);
var worldDyn:bullet.Bt.DynamicsWorld = world;
var worldCol:bullet.Bt.CollisionWorld = worldDyn;
worldCol.rayTest(rayFrom, rayTo, rayCallback);
var rb:RigidBody = null;
if (rayCallback.hasHit()) {
var rc:bullet.Bt.RayResultCallback = rayCallback;
if (rc.hasHit()) {
#if js
var co = rayCallback.get_m_collisionObject();
var body = untyped Ammo.btRigidBody.prototype.upcast(co);
var body = untyped bullet.Bt.Ammo.btRigidBody.prototype.upcast(co);
var hit = rayCallback.get_m_hitPointWorld();
hitPointWorld.set(hit.x(), hit.y(), hit.z());
var norm = rayCallback.get_m_hitNormalWorld();
@ -330,7 +334,9 @@ class PhysicsWorld extends Trait {
}
#if js
Ammo.destroy(rayCallback);
bullet.Bt.Ammo.destroy(rayCallback);
#else
rayCallback.delete();
#end
return rb;

View file

@ -2,7 +2,6 @@ package armory.trait.physics.bullet;
#if arm_bullet
import haxebullet.Bullet;
import iron.math.Vec4;
import iron.math.Quat;
import iron.object.Transform;
@ -40,9 +39,9 @@ class RigidBody extends iron.Trait {
var currentScaleY:Float;
var currentScaleZ:Float;
public var body:BtRigidBodyPointer = null;
public var motionState:BtMotionStatePointer;
public var btshape:BtCollisionShapePointer;
public var body:bullet.Bt.RigidBody = null;
public var motionState:bullet.Bt.MotionState;
public var btshape:bullet.Bt.CollisionShape;
public var ready = false;
static var nextId = 0;
public var id = 0;
@ -50,48 +49,50 @@ class RigidBody extends iron.Trait {
public var onContact:Array<RigidBody->Void> = null;
static var nullvec = true;
static var vec1:BtVector3;
static var vec2:BtVector3;
static var vec3:BtVector3;
static var quat1:BtQuaternion;
static var trans1:BtTransform;
static var trans2:BtTransform;
static var vec1:bullet.Bt.Vector3;
static var vec2:bullet.Bt.Vector3;
static var vec3:bullet.Bt.Vector3;
static var quat1:bullet.Bt.Quaternion;
static var trans1:bullet.Bt.Transform;
static var trans2:bullet.Bt.Transform;
static var quat = new Quat();
public function new(mass = 1.0, shape = Shape.Box, friction = 0.5, restitution = 0.0, collisionMargin = 0.0,
linearDamping = 0.04, angularDamping = 0.1, animated = false,
linearFactors:Array<Float> = null, angularFactors:Array<Float> = null,
group = 1, trigger = false, deactivationParams:Array<Float> = null, ccd = false) {
public function new(shape = Shape.Box, mass = 1.0, friction = 0.5, restitution = 0.0, group = 1,
params:Array<Float> = null, flags:Array<Bool>) {
super();
if (nullvec) {
nullvec = false;
vec1 = BtVector3.create(0, 0, 0);
vec2 = BtVector3.create(0, 0, 0);
vec3 = BtVector3.create(0, 0, 0);
quat1 = BtQuaternion.create(0, 0, 0, 0);
trans1 = BtTransform.create();
trans2 = BtTransform.create();
vec1 = new bullet.Bt.Vector3(0, 0, 0);
vec2 = new bullet.Bt.Vector3(0, 0, 0);
vec3 = new bullet.Bt.Vector3(0, 0, 0);
quat1 = new bullet.Bt.Quaternion(0, 0, 0, 0);
trans1 = new bullet.Bt.Transform();
trans2 = new bullet.Bt.Transform();
}
this.mass = mass;
this.shape = shape;
this.mass = mass;
this.friction = friction;
this.restitution = restitution;
this.collisionMargin = collisionMargin;
this.linearDamping = linearDamping;
this.angularDamping = angularDamping;
this.animated = animated;
this.linearFactors = linearFactors;
this.angularFactors = angularFactors;
this.group = group;
this.trigger = trigger;
this.deactivationParams = deactivationParams;
this.ccd = ccd;
if (params == null) params = [0.04, 0.1, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0];
if (flags == null) flags = [false, false, false];
this.linearDamping = params[0];
this.angularDamping = params[1];
this.linearFactors = [params[2], params[3], params[4]];
this.angularFactors = [params[5], params[6], params[7]];
this.collisionMargin = params[8];
this.deactivationParams = [params[9], params[10], params[11]];
this.animated = flags[0];
this.trigger = flags[1];
this.ccd = flags[2];
notifyOnAdd(init);
}
inline function withMargin(f:Float) {
return f - f * collisionMargin;
}
@ -114,56 +115,66 @@ class RigidBody extends iron.Trait {
vec1.setX(withMargin(transform.dim.x / 2));
vec1.setY(withMargin(transform.dim.y / 2));
vec1.setZ(withMargin(transform.dim.z / 2));
btshape = BtBoxShape.create(vec1);
btshape = new bullet.Bt.BoxShape(vec1);
}
else if (shape == Shape.Sphere) {
btshape = BtSphereShape.create(withMargin(transform.dim.x / 2));
btshape = new bullet.Bt.SphereShape(withMargin(transform.dim.x / 2));
}
else if (shape == Shape.ConvexHull) {
var shapeConvex = BtConvexHullShape.create();
var shapeConvex = new bullet.Bt.ConvexHullShape();
fillConvexHull(shapeConvex, transform.scale, collisionMargin);
btshape = shapeConvex;
}
else if (shape == Shape.Cone) {
btshape = BtConeShapeZ.create(
var coneZ = new bullet.Bt.ConeShapeZ(
withMargin(transform.dim.x / 2), // Radius
withMargin(transform.dim.z)); // Height
var cone:bullet.Bt.ConeShape = coneZ;
btshape = cone;
}
else if (shape == Shape.Cylinder) {
vec1.setX(withMargin(transform.dim.x / 2));
vec1.setY(withMargin(transform.dim.y / 2));
vec1.setZ(withMargin(transform.dim.z / 2));
btshape = BtCylinderShapeZ.create(vec1);
var cylZ = new bullet.Bt.CylinderShapeZ(vec1);
var cyl:bullet.Bt.CylinderShape = cylZ;
btshape = cyl;
}
else if (shape == Shape.Capsule) {
var r = transform.dim.x / 2;
btshape = BtCapsuleShapeZ.create(
var capsZ = new bullet.Bt.CapsuleShapeZ(
withMargin(r), // Radius
withMargin(transform.dim.z - r * 2)); // Height between 2 sphere centers
var caps:bullet.Bt.CapsuleShape = capsZ;
btshape = caps;
}
else if (shape == Shape.Mesh || shape == Shape.Terrain) {
var meshInterface = BtTriangleMesh.create(true, true);
var meshInterface = new bullet.Bt.TriangleMesh(true, true);
fillTriangleMesh(meshInterface, transform.scale);
if (mass > 0) {
var shapeGImpact = BtGImpactMeshShape.create(meshInterface);
var shapeGImpact = new bullet.Bt.GImpactMeshShape(meshInterface);
shapeGImpact.updateBound();
btshape = shapeGImpact;
var shapeConcave:bullet.Bt.ConcaveShape = shapeGImpact;
btshape = shapeConcave;
if (!physics.gimpactRegistered) {
#if js
GImpactCollisionAlgorithm.create().registerAlgorithm(physics.dispatcher);
new bullet.Bt.GImpactCollisionAlgorithm().registerAlgorithm(physics.dispatcher);
#else
BtGImpactCollisionAlgorithm.registerAlgorithm(physics.dispatcher);
shapeGImpact.registerAlgorithm(physics.dispatcher);
#end
physics.gimpactRegistered = true;
}
}
else {
btshape = BtBvhTriangleMeshShape.create(meshInterface, true, true);
var shapeBvh = new bullet.Bt.BvhTriangleMeshShape(meshInterface, true, true);
var shapeTri:bullet.Bt.TriangleMeshShape = shapeBvh;
var shapeConcave:bullet.Bt.ConcaveShape = shapeTri;
btshape = shapeConcave;
}
}
//else if (shape == Shape.Terrain) {
// var data:Array<Dynamic> = [];
// btshape = BtHeightfieldTerrainShape.create(3, 3, data, 1, -10, 10, 2, 0, true);
// btshape = new bullet.Bt.HeightfieldTerrainShape(3, 3, data, 1, -10, 10, 2, 0, true);
//}
trans1.setIdentity();
@ -172,29 +183,28 @@ class RigidBody extends iron.Trait {
vec1.setZ(transform.worldz());
trans1.setOrigin(vec1);
quat.fromMat(transform.world);
quat1.setX(quat.x);
quat1.setY(quat.y);
quat1.setZ(quat.z);
quat1.setW(quat.w);
quat1.setValue(quat.x, quat.y, quat.z, quat.w);
trans1.setRotation(quat1);
var centerOfMassOffset = trans2;
centerOfMassOffset.setIdentity();
motionState = BtDefaultMotionState.create(trans1, centerOfMassOffset);
motionState = new bullet.Bt.DefaultMotionState(trans1, centerOfMassOffset);
vec1.setX(0);
vec1.setY(0);
vec1.setZ(0);
var inertia = vec1;
if (mass > 0) btshape.calculateLocalInertia(mass, inertia);
var bodyCI = BtRigidBodyConstructionInfo.create(mass, motionState, btshape, inertia);
body = BtRigidBody.create(bodyCI);
body.setFriction(friction);
var bodyCI = new bullet.Bt.RigidBodyConstructionInfo(mass, motionState, btshape, inertia);
body = new bullet.Bt.RigidBody(bodyCI);
var bodyColl:bullet.Bt.CollisionObject = body;
bodyColl.setFriction(friction);
// body.setRollingFriction(friction); // This causes bodies to get stuck, apply angular damping instead
if (shape == Shape.Sphere || shape == Shape.Cylinder || shape == Shape.Cone || shape == Shape.Capsule) {
angularDamping += friction;
}
body.setRestitution(restitution);
bodyColl.setRestitution(restitution);
if (deactivationParams != null) {
setDeactivationParams(deactivationParams[0], deactivationParams[1], deactivationParams[2]);
@ -215,7 +225,8 @@ class RigidBody extends iron.Trait {
setAngularFactor(angularFactors[0], angularFactors[1], angularFactors[2]);
}
if (trigger) body.setCollisionFlags(body.getCollisionFlags() | BtCollisionObject.CF_NO_CONTACT_RESPONSE);
var CF_NO_CONTACT_RESPONSE = 4; // bullet.Bt.CollisionObject.CF_NO_CONTACT_RESPONSE
if (trigger) bodyColl.setCollisionFlags(bodyColl.getCollisionFlags() | CF_NO_CONTACT_RESPONSE);
if (ccd) setCcd(transform.radius);
@ -229,8 +240,8 @@ class RigidBody extends iron.Trait {
#if js
//body.setUserIndex(nextId);
untyped body.userIndex = id;
#elseif cpp
body.setUserIndex(id);
#else
bodyColl.setUserIndex(id);
#end
physics.addRigidBody(this);
@ -239,7 +250,9 @@ class RigidBody extends iron.Trait {
if (onReady != null) onReady();
#if js
Ammo.destroy(bodyCI);
bullet.Bt.Ammo.destroy(bodyCI);
#else
bodyCI.delete();
#end
}
@ -249,11 +262,15 @@ class RigidBody extends iron.Trait {
syncTransform();
}
else {
var trans = body.getWorldTransform();
var bodyColl:bullet.Bt.CollisionObject = body;
var trans = bodyColl.getWorldTransform();
var p = trans.getOrigin();
var q = trans.getRotation();
var qw:bullet.Bt.QuadWord = q;
transform.loc.set(p.x(), p.y(), p.z());
transform.rot.set(q.x(), q.y(), q.z(), q.w());
transform.rot.set(qw.x(), qw.y(), qw.z(), qw.w());
if (object.parent != null) {
var ptransform = object.parent.transform;
transform.loc.x -= ptransform.worldx();
@ -274,13 +291,12 @@ class RigidBody extends iron.Trait {
}
public function activate() {
body.activate(false);
var bodyColl:bullet.Bt.CollisionObject = body;
bodyColl.activate(false);
}
public function disableGravity() {
vec1.setX(0);
vec1.setY(0);
vec1.setZ(0);
vec1.setValue(0, 0, 0);
body.setGravity(vec1);
}
@ -289,14 +305,13 @@ class RigidBody extends iron.Trait {
}
public function setGravity(v:Vec4) {
vec1.setX(v.x);
vec1.setY(v.y);
vec1.setZ(v.z);
vec1.setValue(v.x, v.y, v.z);
body.setGravity(vec1);
}
public function setActivationState(newState:Int) {
body.setActivationState(newState);
var bodyColl:bullet.Bt.CollisionObject = body;
bodyColl.setActivationState(newState);
}
public function setDeactivationParams(linearThreshold:Float, angularThreshold:Float, time:Float) {
@ -306,63 +321,47 @@ class RigidBody extends iron.Trait {
public function applyForce(force:Vec4, loc:Vec4 = null) {
activate();
vec1.setX(force.x);
vec1.setY(force.y);
vec1.setZ(force.z);
vec1.setValue(force.x, force.y, force.z);
if (loc == null) {
body.applyCentralForce(vec1);
}
else {
vec2.setX(loc.x);
vec2.setY(loc.y);
vec2.setZ(loc.z);
vec2.setValue(loc.x, loc.y, loc.z);
body.applyForce(vec1, vec2);
}
}
public function applyImpulse(impulse:Vec4, loc:Vec4 = null) {
activate();
vec1.setX(impulse.x);
vec1.setY(impulse.y);
vec1.setZ(impulse.z);
vec1.setValue(impulse.x, impulse.y, impulse.z);
if (loc == null) {
body.applyCentralImpulse(vec1);
}
else {
vec2.setX(loc.x);
vec2.setY(loc.y);
vec2.setZ(loc.z);
vec2.setValue(loc.x, loc.y, loc.z);
body.applyImpulse(vec1, vec2);
}
}
public function applyTorque(torque:Vec4) {
activate();
vec1.setX(torque.x);
vec1.setY(torque.y);
vec1.setZ(torque.z);
vec1.setValue(torque.x, torque.y, torque.z);
body.applyTorque(vec1);
}
public function applyTorqueImpulse(torque:Vec4) {
activate();
vec1.setX(torque.x);
vec1.setY(torque.y);
vec1.setZ(torque.z);
vec1.setValue(torque.x, torque.y, torque.z);
body.applyTorqueImpulse(vec1);
}
public function setLinearFactor(x:Float, y:Float, z:Float) {
vec1.setX(x);
vec1.setY(y);
vec1.setZ(z);
vec1.setValue(x, y, z);
body.setLinearFactor(vec1);
}
public function setAngularFactor(x:Float, y:Float, z:Float) {
vec1.setX(x);
vec1.setY(y);
vec1.setZ(z);
vec1.setValue(x, y, z);
body.setAngularFactor(vec1);
}
@ -372,9 +371,7 @@ class RigidBody extends iron.Trait {
}
public function setLinearVelocity(x:Float, y:Float, z:Float) {
vec1.setX(x);
vec1.setY(y);
vec1.setZ(z);
vec1.setValue(x, y, z);
body.setLinearVelocity(vec1);
}
@ -384,15 +381,14 @@ class RigidBody extends iron.Trait {
}
public function setAngularVelocity(x:Float, y:Float, z:Float) {
vec1.setX(x);
vec1.setY(y);
vec1.setZ(z);
vec1.setValue(x, y, z);
body.setAngularVelocity(vec1);
}
public function setFriction(f:Float) {
body.setFriction(f);
body.setRollingFriction(f);
var bodyColl:bullet.Bt.CollisionObject = body;
bodyColl.setFriction(f);
// bodyColl.setRollingFriction(f);
this.friction = f;
}
@ -405,30 +401,6 @@ class RigidBody extends iron.Trait {
onContact.remove(f);
}
public function syncTransform() {
var t = transform;
t.buildMatrix();
vec1.setX(t.worldx());
vec1.setY(t.worldy());
vec1.setZ(t.worldz());
trans1.setOrigin(vec1);
quat.fromMat(t.world);
quat1.setX(quat.x);
quat1.setY(quat.y);
quat1.setZ(quat.z);
quat1.setW(quat.w);
trans1.setRotation(quat1);
body.setCenterOfMassTransform(trans1);
if (currentScaleX != t.scale.x || currentScaleY != t.scale.y || currentScaleZ != t.scale.z) setScale(t.scale);
activate();
}
// Continuous collision detection
public function setCcd(sphereRadius:Float, motionThreshold = 1e-7) {
body.setCcdSweptSphereRadius(sphereRadius);
body.setCcdMotionThreshold(motionThreshold);
}
function setScale(v:Vec4) {
currentScaleX = v.x;
currentScaleY = v.y;
@ -437,39 +409,79 @@ class RigidBody extends iron.Trait {
vec1.setY(bodyScaleY * v.y);
vec1.setZ(bodyScaleZ * v.z);
btshape.setLocalScaling(vec1);
physics.world.updateSingleAabb(body);
var worldDyn:bullet.Bt.DynamicsWorld = physics.world;
var worldCol:bullet.Bt.CollisionWorld = worldDyn;
worldCol.updateSingleAabb(body);
}
function fillConvexHull(shape:BtConvexHullShapePointer, scale:Vec4, margin:Float) {
var positions = cast(object, MeshObject).data.geom.positions;
public function syncTransform() {
var t = transform;
t.buildMatrix();
vec1.setValue(t.worldx(), t.worldy(), t.worldz());
trans1.setOrigin(vec1);
quat.fromMat(t.world);
quat1.setValue(quat.x, quat.y, quat.z, quat.w);
trans1.setRotation(quat1);
body.setCenterOfMassTransform(trans1);
if (currentScaleX != t.scale.x || currentScaleY != t.scale.y || currentScaleZ != t.scale.z) setScale(t.scale);
activate();
}
var sx = scale.x * (1.0 - margin);
var sy = scale.y * (1.0 - margin);
var sz = scale.z * (1.0 - margin);
// Continuous collision detection
public function setCcd(sphereRadius:Float, motionThreshold = 1e-7) {
var bodyColl:bullet.Bt.CollisionObject = body;
bodyColl.setCcdSweptSphereRadius(sphereRadius);
bodyColl.setCcdMotionThreshold(motionThreshold);
}
for (i in 0...Std.int(positions.length / 3)) {
vec1.setX(positions[i * 3] * sx);
vec1.setY(positions[i * 3 + 1] * sy);
vec1.setZ(positions[i * 3 + 2] * sz);
function fillConvexHull(shape:bullet.Bt.ConvexHullShape, scale:Vec4, margin:kha.FastFloat) {
var data = cast(object, MeshObject).data;
var positions = data.geom.positions;
var sx:kha.FastFloat = scale.x * (1.0 - margin) * (1 / 32767);
var sy:kha.FastFloat = scale.y * (1.0 - margin) * (1 / 32767);
var sz:kha.FastFloat = scale.z * (1.0 - margin) * (1 / 32767);
if (data.raw.scale_pos != null) {
sx *= data.raw.scale_pos;
sy *= data.raw.scale_pos;
sz *= data.raw.scale_pos;
}
for (i in 0...Std.int(positions.length / 4)) {
vec1.setX(positions[i * 4 ] * sx);
vec1.setY(positions[i * 4 + 1] * sy);
vec1.setZ(positions[i * 4 + 2] * sz);
shape.addPoint(vec1, true);
}
}
function fillTriangleMesh(triangleMesh:BtTriangleMeshPointer, scale:Vec4) {
var positions = cast(object, MeshObject).data.geom.positions;
var indices = cast(object, MeshObject).data.geom.indices;
function fillTriangleMesh(triangleMesh:bullet.Bt.TriangleMesh, scale:Vec4) {
var data = cast(object, MeshObject).data;
var positions = data.geom.positions;
var indices = data.geom.indices;
var sx:kha.FastFloat = scale.x * (1 / 32767);
var sy:kha.FastFloat = scale.y * (1 / 32767);
var sz:kha.FastFloat = scale.z * (1 / 32767);
if (data.raw.scale_pos != null) {
sx *= data.raw.scale_pos;
sy *= data.raw.scale_pos;
sz *= data.raw.scale_pos;
}
for (ar in indices) {
for (i in 0...Std.int(ar.length / 3)) {
vec1.setX(positions[ar[i * 3 + 0] * 3 + 0] * scale.x);
vec1.setY(positions[ar[i * 3 + 0] * 3 + 1] * scale.y);
vec1.setZ(positions[ar[i * 3 + 0] * 3 + 2] * scale.z);
vec2.setX(positions[ar[i * 3 + 1] * 3 + 0] * scale.x);
vec2.setY(positions[ar[i * 3 + 1] * 3 + 1] * scale.y);
vec2.setZ(positions[ar[i * 3 + 1] * 3 + 2] * scale.z);
vec3.setX(positions[ar[i * 3 + 2] * 3 + 0] * scale.x);
vec3.setY(positions[ar[i * 3 + 2] * 3 + 1] * scale.y);
vec3.setZ(positions[ar[i * 3 + 2] * 3 + 2] * scale.z);
vec1.setX(positions[ar[i * 3 + 0] * 4 + 0] * sx);
vec1.setY(positions[ar[i * 3 + 0] * 4 + 1] * sy);
vec1.setZ(positions[ar[i * 3 + 0] * 4 + 2] * sz);
vec2.setX(positions[ar[i * 3 + 1] * 4 + 0] * sx);
vec2.setY(positions[ar[i * 3 + 1] * 4 + 1] * sy);
vec2.setZ(positions[ar[i * 3 + 1] * 4 + 2] * sz);
vec3.setX(positions[ar[i * 3 + 2] * 4 + 0] * sx);
vec3.setY(positions[ar[i * 3 + 2] * 4 + 1] * sy);
vec3.setZ(positions[ar[i * 3 + 2] * 4 + 2] * sz);
triangleMesh.addTriangle(vec1, vec2, vec3);
}
}

View file

@ -11,7 +11,6 @@ import iron.data.SceneFormat;
#if arm_physics_soft
import armory.trait.physics.RigidBody;
import armory.trait.physics.PhysicsWorld;
import haxebullet.Bullet;
#end
class SoftBody extends Trait {
@ -31,11 +30,11 @@ class SoftBody extends Trait {
public var vertOffsetY = 0.0;
public var vertOffsetZ = 0.0;
public var body:BtSoftBodyPointer;
public var body:bullet.Bt.SoftBody;
static var helpers:BtSoftBodyHelpers;
static var helpers:bullet.Bt.SoftBodyHelpers;
static var helpersCreated = false;
static var worldInfo:BtSoftBodyWorldInfo;
static var worldInfo:bullet.Bt.SoftBodyWorldInfo;
public function new(shape = SoftShape.Cloth, bend = 0.5, mass = 1.0, margin = 0.04) {
super();
@ -90,7 +89,7 @@ class SoftBody extends Trait {
}
var positions = fromF32(geom.positions);
for (i in 0...Std.int(positions.length / 3)) {
for (i in 0...Std.int(positions.length / 4)) {
v.set(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
v.applyQuat(object.transform.rot);
v.x *= object.transform.scale.x;
@ -115,7 +114,7 @@ class SoftBody extends Trait {
for (ar in geom.indices) numtri += Std.int(ar.length / 3);
if (!helpersCreated) {
helpers = BtSoftBodyHelpers.create();
helpers = new bullet.Bt.SoftBodyHelpers();
worldInfo = physics.world.getWorldInfo();
helpersCreated = true;
}

View file

@ -3,7 +3,7 @@
bl_info = {
"name": "Armory",
"category": "Render",
"location": "Properties -> Render -> Armory",
"location": "Properties -> Render -> Armory Player",
"description": "3D Game Engine for Blender",
"author": "Armory3D.org",
"version": (0, 6, 0),
@ -55,43 +55,43 @@ class ArmoryAddonPreferences(AddonPreferences):
self.skip_update = True
self.renderdoc_path = bpy.path.reduce_dirs([bpy.path.abspath(self.renderdoc_path)])[0]
sdk_bundled = BoolProperty(name="Bundled SDK", default=True)
sdk_path = StringProperty(name="SDK Path", subtype="FILE_PATH", update=sdk_path_update, default="")
show_advanced = BoolProperty(name="Show Advanced", default=False)
player_gapi_win = EnumProperty(
items = [('opengl', 'Auto', 'opengl'),
sdk_bundled: BoolProperty(name="Bundled SDK", default=True)
sdk_path: StringProperty(name="SDK Path", subtype="FILE_PATH", update=sdk_path_update, default="")
show_advanced: BoolProperty(name="Show Advanced", default=False)
player_gapi_win: EnumProperty(
items = [('direct3d11', 'Auto', 'direct3d11'),
('opengl', 'OpenGL', 'opengl'),
('direct3d11', 'Direct3D11', 'direct3d11')],
name="Player Graphics API", default='opengl', description='Use this graphics API when launching the game in Krom player(F5)')
player_gapi_linux = EnumProperty(
name="Player Graphics API", default='direct3d11', description='Use this graphics API when launching the game in Krom player(F5)')
player_gapi_linux: EnumProperty(
items = [('opengl', 'Auto', 'opengl'),
('opengl', 'OpenGL', 'opengl')],
name="Player Graphics API", default='opengl', description='Use this graphics API when launching the game in Krom player(F5)')
player_gapi_mac = EnumProperty(
player_gapi_mac: EnumProperty(
items = [('opengl', 'Auto', 'opengl'),
('opengl', 'OpenGL', 'opengl')],
name="Player Graphics API", default='opengl', description='Use this graphics API when launching the game in Krom player(F5)')
code_editor = EnumProperty(
code_editor: EnumProperty(
items = [('kodestudio', 'Kode Studio', 'kodestudio'),
('default', 'System Default', 'default')],
name="Code Editor", default='kodestudio', description='Use this editor for editing scripts')
ui_scale = FloatProperty(name='UI Scale', description='Adjust UI scale for Armory tools', default=1.0, min=1.0, max=4.0)
khamake_threads = IntProperty(name='Khamake Threads', description='Allow Khamake to spawn multiple processes for faster builds', default=4, min=1)
renderdoc_path = StringProperty(name="RenderDoc Path", description="Binary path", subtype="FILE_PATH", update=renderdoc_path_update, default="")
ffmpeg_path = StringProperty(name="FFMPEG Path", description="Binary path", subtype="FILE_PATH", update=ffmpeg_path_update, default="")
save_on_build = BoolProperty(name="Save on Build", description="Save .blend", default=False)
legacy_shaders = BoolProperty(name="Legacy Shaders", description="Attempt to compile shaders runnable on older hardware", default=False)
relative_paths = BoolProperty(name="Generate Relative Paths", description="Write relative paths in khafile", default=False)
viewport_controls = EnumProperty(
ui_scale: FloatProperty(name='UI Scale', description='Adjust UI scale for Armory tools', default=1.0, min=1.0, max=4.0)
khamake_threads: IntProperty(name='Khamake Threads', description='Allow Khamake to spawn multiple processes for faster builds', default=4, min=1)
renderdoc_path: StringProperty(name="RenderDoc Path", description="Binary path", subtype="FILE_PATH", update=renderdoc_path_update, default="")
ffmpeg_path: StringProperty(name="FFMPEG Path", description="Binary path", subtype="FILE_PATH", update=ffmpeg_path_update, default="")
save_on_build: BoolProperty(name="Save on Build", description="Save .blend", default=False)
legacy_shaders: BoolProperty(name="Legacy Shaders", description="Attempt to compile shaders runnable on older hardware", default=False)
relative_paths: BoolProperty(name="Generate Relative Paths", description="Write relative paths in khafile", default=False)
viewport_controls: EnumProperty(
items=[('qwerty', 'qwerty', 'qwerty'),
('azerty', 'azerty', 'azerty')],
name="Viewport Controls", default='qwerty', description='Viewport camera mode controls')
skip_update = BoolProperty(name="", default=False)
skip_update: BoolProperty(name="", default=False)
def draw(self, context):
self.skip_update = False
layout = self.layout
layout.label(text="Welcome to Armory! Click 'Save User Settings' at the bottom to keep Armory enabled.")
layout.label(text="Welcome to Armory! Click 'Save Preferences' at the bottom to keep Armory enabled.")
p = bundled_sdk_path()
if os.path.exists(p):
layout.prop(self, "sdk_bundled")
@ -113,7 +113,6 @@ class ArmoryAddonPreferences(AddonPreferences):
box = layout.box().column()
box.prop(self, "player_gapi_" + get_os())
box.prop(self, "code_editor")
# box.prop(self, "kha_version")
box.prop(self, "renderdoc_path")
box.prop(self, "ffmpeg_path")
box.prop(self, "viewport_controls")
@ -192,153 +191,6 @@ class ArmAddonStartButton(bpy.types.Operator):
running = False
def execute(self, context):
if bpy.app.version >= (2, 80, 1):
from bl_ui import properties_render
# properties_render.RENDER_PT_render.COMPAT_ENGINES.add('ARMORY')
# properties_render.RENDER_PT_output.COMPAT_ENGINES.add('ARMORY')
properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_world
properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('ARMORY')
properties_world.WORLD_PT_custom_props.COMPAT_ENGINES.add('ARMORY')
properties_world.EEVEE_WORLD_PT_surface.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_material
properties_material.MATERIAL_PT_preview.COMPAT_ENGINES.add('ARMORY')
properties_material.MATERIAL_PT_custom_props.COMPAT_ENGINES.add('ARMORY')
properties_material.EEVEE_MATERIAL_PT_context_material.COMPAT_ENGINES.add('ARMORY')
properties_material.EEVEE_MATERIAL_PT_surface.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_object
properties_object.OBJECT_PT_custom_props.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_particle
properties_particle.PARTICLE_MT_specials.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_context_particles.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_emission.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_hair_dynamics.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_cache.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_velocity.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_rotation.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_physics.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_boidbrain.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_render.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_draw.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_children.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_field_weights.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_force_fields.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_vertexgroups.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_textures.COMPAT_ENGINES.add('ARMORY')
properties_particle.PARTICLE_PT_custom_props.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_scene
properties_scene.SCENE_PT_scene.COMPAT_ENGINES.add('ARMORY')
properties_scene.SCENE_PT_unit.COMPAT_ENGINES.add('ARMORY')
properties_scene.SCENE_PT_color_management.COMPAT_ENGINES.add('ARMORY')
properties_scene.SCENE_PT_audio.COMPAT_ENGINES.add('ARMORY')
properties_scene.SCENE_PT_physics.COMPAT_ENGINES.add('ARMORY')
properties_scene.SCENE_PT_rigid_body_world.COMPAT_ENGINES.add('ARMORY')
properties_scene.SCENE_PT_rigid_body_cache.COMPAT_ENGINES.add('ARMORY')
properties_scene.SCENE_PT_rigid_body_field_weights.COMPAT_ENGINES.add('ARMORY')
properties_scene.SCENE_PT_custom_props.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_texture
properties_texture.TEXTURE_MT_specials.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_preview.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_context.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_node.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_node_mapping.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_colors.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_clouds.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_wood.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_marble.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_magic.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_blend.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_stucci.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_image.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_image_sampling.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_image_mapping.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_musgrave.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_voronoi.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_distortednoise.COMPAT_ENGINES.add('ARMORY')
properties_texture.TextureSlotPanel.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_mapping.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_influence.COMPAT_ENGINES.add('ARMORY')
properties_texture.TEXTURE_PT_custom_props.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_armature
properties_data_armature.DATA_PT_custom_props_arm.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_bone
properties_data_bone.BONE_PT_custom_props.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_camera
properties_data_camera.DATA_PT_context_camera.COMPAT_ENGINES.add('ARMORY')
properties_data_camera.DATA_PT_lens.COMPAT_ENGINES.add('ARMORY')
properties_data_camera.DATA_PT_camera_stereoscopy.COMPAT_ENGINES.add('ARMORY')
properties_data_camera.DATA_PT_camera_dof.COMPAT_ENGINES.add('ARMORY')
properties_data_camera.DATA_PT_camera_background_image.COMPAT_ENGINES.add('ARMORY')
properties_data_camera.DATA_PT_camera_display.COMPAT_ENGINES.add('ARMORY')
properties_data_camera.DATA_PT_camera_safe_areas.COMPAT_ENGINES.add('ARMORY')
properties_data_camera.DATA_PT_custom_props_camera.COMPAT_ENGINES.add('ARMORY')
properties_data_camera.DATA_PT_custom_props_camera.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_curve
properties_data_curve.DATA_PT_curve_texture_space.COMPAT_ENGINES.add('ARMORY')
properties_data_curve.DATA_PT_custom_props_curve.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_light
properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add('ARMORY')
properties_data_light.DATA_PT_preview.COMPAT_ENGINES.add('ARMORY')
# properties_data_light.DATA_PT_light.COMPAT_ENGINES.add('ARMORY')
properties_data_light.DATA_PT_EEVEE_light.COMPAT_ENGINES.add('ARMORY')
properties_data_light.DATA_PT_EEVEE_shadow.COMPAT_ENGINES.add('ARMORY')
properties_data_light.DATA_PT_area.COMPAT_ENGINES.add('ARMORY')
properties_data_light.DATA_PT_spot.COMPAT_ENGINES.add('ARMORY')
properties_data_light.DATA_PT_falloff_curve.COMPAT_ENGINES.add('ARMORY')
properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_lattice
properties_data_lattice.DATA_PT_custom_props_lattice.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_lightprobe
properties_data_lightprobe.DATA_PT_context_lightprobe.COMPAT_ENGINES.add('ARMORY')
properties_data_lightprobe.DATA_PT_lightprobe.COMPAT_ENGINES.add('ARMORY')
properties_data_lightprobe.DATA_PT_lightprobe_parallax.COMPAT_ENGINES.add('ARMORY')
properties_data_lightprobe.DATA_PT_lightprobe_display.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_mesh
properties_data_mesh.DATA_PT_context_mesh.COMPAT_ENGINES.add('ARMORY')
properties_data_mesh.DATA_PT_normals.COMPAT_ENGINES.add('ARMORY')
properties_data_mesh.DATA_PT_texture_space.COMPAT_ENGINES.add('ARMORY')
properties_data_mesh.DATA_PT_vertex_groups.COMPAT_ENGINES.add('ARMORY')
properties_data_mesh.DATA_PT_face_maps.COMPAT_ENGINES.add('ARMORY')
properties_data_mesh.DATA_PT_shape_keys.COMPAT_ENGINES.add('ARMORY')
properties_data_mesh.DATA_PT_uv_texture.COMPAT_ENGINES.add('ARMORY')
properties_data_mesh.DATA_PT_vertex_colors.COMPAT_ENGINES.add('ARMORY')
properties_data_mesh.DATA_PT_customdata.COMPAT_ENGINES.add('ARMORY')
properties_data_mesh.DATA_PT_custom_props_mesh.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_metaball
properties_data_metaball.DATA_PT_mball_texture_space.COMPAT_ENGINES.add('ARMORY')
properties_data_metaball.DATA_PT_custom_props_metaball.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_data_speaker
properties_data_speaker.DATA_PT_context_speaker.COMPAT_ENGINES.add('ARMORY')
properties_data_speaker.DATA_PT_speaker.COMPAT_ENGINES.add('ARMORY')
properties_data_speaker.DATA_PT_distance.COMPAT_ENGINES.add('ARMORY')
properties_data_speaker.DATA_PT_cone.COMPAT_ENGINES.add('ARMORY')
properties_data_speaker.DATA_PT_custom_props_speaker.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_physics_cloth
properties_physics_cloth.PHYSICS_PT_cloth.COMPAT_ENGINES.add('ARMORY')
properties_physics_cloth.PHYSICS_PT_cloth_cache.COMPAT_ENGINES.add('ARMORY')
properties_physics_cloth.PHYSICS_PT_cloth_collision.COMPAT_ENGINES.add('ARMORY')
properties_physics_cloth.PHYSICS_PT_cloth_stiffness.COMPAT_ENGINES.add('ARMORY')
properties_physics_cloth.PHYSICS_PT_cloth_sewing.COMPAT_ENGINES.add('ARMORY')
properties_physics_cloth.PHYSICS_PT_cloth_field_weights.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_physics_common
properties_physics_common.PHYSICS_PT_add.COMPAT_ENGINES.add('ARMORY')
properties_physics_common.PHYSICS_PT_add.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_physics_softbody
properties_physics_softbody.PHYSICS_PT_softbody.COMPAT_ENGINES.add('ARMORY')
properties_physics_softbody.PHYSICS_PT_softbody_cache.COMPAT_ENGINES.add('ARMORY')
properties_physics_softbody.PHYSICS_PT_softbody_goal.COMPAT_ENGINES.add('ARMORY')
properties_physics_softbody.PHYSICS_PT_softbody_edge.COMPAT_ENGINES.add('ARMORY')
properties_physics_softbody.PHYSICS_PT_softbody_collision.COMPAT_ENGINES.add('ARMORY')
properties_physics_softbody.PHYSICS_PT_softbody_solver.COMPAT_ENGINES.add('ARMORY')
properties_physics_softbody.PHYSICS_PT_softbody_field_weights.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_physics_rigidbody
properties_physics_rigidbody.PHYSICS_PT_rigid_body.COMPAT_ENGINES.add('ARMORY')
properties_physics_rigidbody.PHYSICS_PT_rigid_body_collisions.COMPAT_ENGINES.add('ARMORY')
properties_physics_rigidbody.PHYSICS_PT_rigid_body_dynamics.COMPAT_ENGINES.add('ARMORY')
properties_physics_rigidbody.PHYSICS_PT_rigid_body_dynamics.COMPAT_ENGINES.add('ARMORY')
from bl_ui import properties_physics_rigidbody_constraint
properties_physics_rigidbody_constraint.PHYSICS_PT_rigid_body_constraint.COMPAT_ENGINES.add('ARMORY')
sdk_path = get_sdk_path(context)
if sdk_path == "":
print("Configure Armory SDK path first")
@ -395,7 +247,7 @@ class ArmAddonUpdateButton(bpy.types.Operator):
git_clone(done, sdk_path, 'armory3d/zui', 'lib/zui')
git_clone(done, sdk_path, 'armory3d/armory_tools', 'lib/armory_tools')
git_clone(done, sdk_path, 'armory3d/iron_format', 'lib/iron_format')
git_clone(done, sdk_path, 'Kode/Krom_bin', 'Krom')
git_clone(done, sdk_path, 'armory3d/Krom_bin', 'Krom')
git_clone(done, sdk_path, 'Kode/Kha', 'Kha', recursive=True)
return {"FINISHED"}
@ -435,10 +287,6 @@ class ArmAddonHelpButton(bpy.types.Operator):
@persistent
def on_load_post(context):
# Detect local armsdk
# if os.path.exists(get_fp() + '/armsdk'):
# if ArmAddonStartButton.running:
# bpy.ops.arm_addon.stop()
if ArmAddonStartButton.running:
return
bpy.ops.arm_addon.start()

View file

@ -3,18 +3,14 @@ from addon_utils import enable
from bpy.app.handlers import persistent
@persistent
def on_scene_update_post(scene):
if hasattr(bpy.app.handlers, 'scene_update_post'):
bpy.app.handlers.scene_update_post.remove(on_scene_update_post)
# Enable addon by default for Armory integrated in Blender
def handler(scene):
user_preferences = bpy.context.user_preferences
if not 'armory' in user_preferences.addons:
enable('armory', default_set=True, persistent=True, handle_error=None)
bpy.ops.wm.save_userpref()
def register():
if hasattr(bpy.app.handlers, 'scene_update_post'):
bpy.app.handlers.scene_update_post.append(on_scene_update_post)
bpy.app.handlers.load_post.append(handler)
def unregister():
pass

File diff suppressed because it is too large Load diff

View file

@ -106,19 +106,18 @@ def export_grease_pencil_frame(self, frame):
# TODO: merge into array of vertex arrays
fo['vertex_array'] = {}
fo['vertex_array']['attrib'] = 'pos'
fo['vertex_array']['size'] = 3
fo['vertex_array']['data'] = 'short4norm'
fo['vertex_array']['values'] = va
fo['col_array'] = {}
fo['col_array']['attrib'] = 'col'
fo['col_array']['size'] = 4
fo['col_array']['data'] = 'short4norm'
fo['col_array']['values'] = cola
fo['colfill_array'] = {}
fo['colfill_array']['attrib'] = 'colfill'
fo['colfill_array']['size'] = 4
fo['colfill_array']['data'] = 'short4norm'
fo['colfill_array']['values'] = colfilla
fo['index_array'] = {}
fo['index_array']['material'] = 0
fo['index_array']['size'] = 3
fo['index_array']['values'] = indices
fo['num_stroke_points'] = num_stroke_points
fo['frame_number'] = frame.frame_number

309
blender/arm/exporter_opt.py Normal file
View file

@ -0,0 +1,309 @@
import bpy
import numpy as np
from mathutils import *
import arm.utils
# Exports smaller geometry but is slower
# To be replaced with https://github.com/zeux/meshoptimizer
class Vertex:
__slots__ = ("co", "normal", "uvs", "col", "loop_indices", "index", "bone_weights", "bone_indices", "bone_count", "vertex_index")
def __init__(self, mesh, loop):
self.vertex_index = loop.vertex_index
loop_idx = loop.index
self.co = mesh.vertices[self.vertex_index].co[:]
self.normal = loop.normal[:]
self.uvs = tuple(layer.data[loop_idx].uv[:] for layer in mesh.uv_layers)
self.col = [0.0, 0.0, 0.0]
if len(mesh.vertex_colors) > 0:
self.col = mesh.vertex_colors[0].data[loop_idx].color[:]
self.loop_indices = [loop_idx]
self.index = 0
def __hash__(self):
return hash((self.co, self.normal, self.uvs))
def __eq__(self, other):
eq = (
(self.co == other.co) and
(self.normal == other.normal) and
(self.uvs == other.uvs) and
(self.col == other.col)
)
if eq:
indices = self.loop_indices + other.loop_indices
self.loop_indices = indices
other.loop_indices = indices
return eq
def export_mesh_data(self, exportMesh, bobject, o, has_armature=False):
exportMesh.calc_normals_split()
# exportMesh.calc_loop_triangles()
vert_list = { Vertex(exportMesh, loop) : 0 for loop in exportMesh.loops}.keys()
num_verts = len(vert_list)
num_uv_layers = len(exportMesh.uv_layers)
has_tex = self.get_export_uvs(exportMesh) == True and num_uv_layers > 0
if self.has_baked_material(bobject, exportMesh.materials):
has_tex = True
has_tex1 = has_tex == True and num_uv_layers > 1
num_colors = len(exportMesh.vertex_colors)
has_col = self.get_export_vcols(exportMesh) == True and num_colors > 0
has_tang = self.has_tangents(exportMesh)
pdata = np.empty(num_verts * 4, dtype='<f4') # p.xyz, n.z
ndata = np.empty(num_verts * 2, dtype='<f4') # n.xy
if has_tex:
# Get active uvmap
t0map = 0
uv_layers = exportMesh.uv_layers
if uv_layers != None:
if 'UVMap_baked' in uv_layers:
for i in range(0, len(uv_layers)):
if uv_layers[i].name == 'UVMap_baked':
t0map = i
break
else:
for i in range(0, len(uv_layers)):
if uv_layers[i].active_render:
t0map = i
break
t1map = 1 if t0map == 0 else 0
# Alloc data
t0data = np.empty(num_verts * 2, dtype='<f4')
if has_tex1:
t1data = np.empty(num_verts * 2, dtype='<f4')
if has_col:
cdata = np.empty(num_verts * 3, dtype='<f4')
if has_tex:
# Scale for packed coords
maxdim = 1.0
lay0 = exportMesh.uv_layers[t0map]
for v in lay0.data:
if abs(v.uv[0]) > maxdim:
maxdim = abs(v.uv[0])
if abs(v.uv[1]) > maxdim:
maxdim = abs(v.uv[1])
if maxdim > 1:
o['scale_tex'] = maxdim
invscale_tex = (1 / o['scale_tex']) * 32767
else:
invscale_tex = 1 * 32767
# TODO: handle t1map
# Save aabb
aabb_center = 0.125 * sum((Vector(b) for b in bobject.bound_box), Vector())
bobject.data.arm_aabb = [ \
abs((bobject.bound_box[6][0] - bobject.bound_box[0][0]) / 2 + abs(aabb_center[0])) * 2, \
abs((bobject.bound_box[6][1] - bobject.bound_box[0][1]) / 2 + abs(aabb_center[1])) * 2, \
abs((bobject.bound_box[6][2] - bobject.bound_box[0][2]) / 2 + abs(aabb_center[2])) * 2 \
]
# Scale for packed coords
maxdim = max(bobject.data.arm_aabb[0], max(bobject.data.arm_aabb[1], bobject.data.arm_aabb[2]))
o['scale_pos'] = maxdim / 2
if has_armature: # Allow up to 2x bigger bounds for skinned mesh
o['scale_pos'] *= 2.0
scale_pos = o['scale_pos']
invscale_pos = (1 / scale_pos) * 32767
# Make arrays
for i, v in enumerate(vert_list):
v.index = i
co = v.co
normal = v.normal
i4 = i * 4
i2 = i * 2
pdata[i4 ] = co[0]
pdata[i4 + 1] = co[1]
pdata[i4 + 2] = co[2]
pdata[i4 + 3] = normal[2] * scale_pos # Cancel scale
ndata[i2 ] = normal[0]
ndata[i2 + 1] = normal[1]
if has_tex:
uv = v.uvs[t0map]
t0data[i2 ] = uv[0]
t0data[i2 + 1] = 1.0 - uv[1] # Reverse Y
if has_tex1:
uv = v.uvs[t1map]
t1data[i2 ] = uv[0]
t1data[i2 + 1] = 1.0 - uv[1]
if has_col:
i3 = i * 3
cdata[i3 ] = pow(v.col[0], 2.2)
cdata[i3 + 1] = pow(v.col[1], 2.2)
cdata[i3 + 2] = pow(v.col[2], 2.2)
# Indices
prims = {ma.name if ma else '': [] for ma in exportMesh.materials}
if not prims:
prims = {'': []}
vert_dict = {i : v for v in vert_list for i in v.loop_indices}
for poly in exportMesh.polygons:
first = poly.loop_start
if len(exportMesh.materials) == 0:
prim = prims['']
else:
mat = exportMesh.materials[min(poly.material_index, len(exportMesh.materials) - 1)]
prim = prims[mat.name if mat else '']
indices = [vert_dict[i].index for i in range(first, first+poly.loop_total)]
if poly.loop_total == 3:
prim += indices
elif poly.loop_total > 3:
for i in range(poly.loop_total-2):
prim += (indices[-1], indices[i], indices[i + 1])
# Write indices
o['index_arrays'] = []
for mat, prim in prims.items():
idata = [0] * len(prim)
for i, v in enumerate(prim):
idata[i] = v
if len(idata) == 0: # No face assigned
continue
ia = {}
ia['values'] = idata
ia['material'] = 0
# Find material index for multi-mat mesh
if len(exportMesh.materials) > 1:
for i in range(0, len(exportMesh.materials)):
if (exportMesh.materials[i] != None and mat == exportMesh.materials[i].name) or \
(exportMesh.materials[i] == None and mat == ''): # Default material for empty slots
ia['material'] = i
break
o['index_arrays'].append(ia)
if has_tang:
tangdata = self.calc_tangents(pdata, ndata, t0data, o['index_arrays'], scale_pos)
pdata *= invscale_pos
ndata *= 32767
pdata = np.array(pdata, dtype='<i2')
ndata = np.array(ndata, dtype='<i2')
if has_tex:
t0data *= invscale_tex
t0data = np.array(t0data, dtype='<i2')
if has_tex1:
t1data *= invscale_tex
t1data = np.array(t1data, dtype='<i2')
if has_col:
cdata *= 32767
cdata = np.array(cdata, dtype='<i2')
if has_tang:
tangdata *= 32767
tangdata = np.array(tangdata, dtype='<i2')
# Output
o['vertex_arrays'] = []
o['vertex_arrays'].append({ 'attrib': 'pos', 'values': pdata })
o['vertex_arrays'].append({ 'attrib': 'nor', 'values': ndata })
if has_tex:
o['vertex_arrays'].append({ 'attrib': 'tex', 'values': t0data })
if has_tex1:
o['vertex_arrays'].append({ 'attrib': 'tex1', 'values': t1data })
if has_col:
o['vertex_arrays'].append({ 'attrib': 'col', 'values': cdata })
if has_tang:
o['vertex_arrays'].append({ 'attrib': 'tang', 'values': tangdata })
return vert_list
def export_skin(self, bobject, armature, vert_list, o):
# This function exports all skinning data, which includes the skeleton
# and per-vertex bone influence data
oskin = {}
o['skin'] = oskin
# Write the skin bind pose transform
otrans = {}
oskin['transform'] = otrans
otrans['values'] = self.write_matrix(bobject.matrix_world)
# Write the bone object reference array
oskin['bone_ref_array'] = []
oskin['bone_len_array'] = []
bone_array = armature.data.bones
bone_count = len(bone_array)
rpdat = arm.utils.get_rp()
max_bones = rpdat.arm_skin_max_bones
if bone_count > max_bones:
log.warn(bobject.name + ' - ' + str(bone_count) + ' bones found, exceeds maximum of ' + str(max_bones) + ' bones defined - raise the value in Camera Data - Armory Render Props - Max Bones')
for i in range(bone_count):
boneRef = self.find_bone(bone_array[i].name)
if boneRef:
oskin['bone_ref_array'].append(boneRef[1]["structName"])
oskin['bone_len_array'].append(bone_array[i].length)
else:
oskin['bone_ref_array'].append("")
oskin['bone_len_array'].append(0.0)
# Write the bind pose transform array
oskin['transformsI'] = []
if rpdat.arm_skin == 'CPU':
for i in range(bone_count):
skeletonI = (armature.matrix_world @ bone_array[i].matrix_local).inverted_safe()
oskin['transformsI'].append(self.write_matrix(skeletonI))
else:
for i in range(bone_count):
skeletonI = (armature.matrix_world @ bone_array[i].matrix_local).inverted_safe()
skeletonI = (skeletonI @ bobject.matrix_world)
oskin['transformsI'].append(self.write_matrix(skeletonI))
# Export the per-vertex bone influence data
group_remap = []
for group in bobject.vertex_groups:
for i in range(bone_count):
if bone_array[i].name == group.name:
group_remap.append(i)
break
else:
group_remap.append(-1)
bone_count_array = np.empty(len(vert_list), dtype='<i2')
bone_index_array = np.empty(len(vert_list) * 4, dtype='<i2')
bone_weight_array = np.empty(len(vert_list) * 4, dtype='<i2')
vertices = bobject.data.vertices
count = 0
for index, v in enumerate(vert_list):
bone_count = 0
total_weight = 0.0
bone_values = []
for g in vertices[v.vertex_index].groups:
bone_index = group_remap[g.group]
bone_weight = g.weight
if bone_index >= 0: #and bone_weight != 0.0:
bone_values.append((bone_weight, bone_index))
total_weight += bone_weight
bone_count += 1
if bone_count > 4:
bone_count = 4
bone_values.sort(reverse=True)
bone_values = bone_values[:4]
bone_count_array[index] = bone_count
for bv in bone_values:
bone_weight_array[count] = bv[0] * 32767
bone_index_array[count] = bv[1]
count += 1
if total_weight != 0.0 and total_weight != 1.0:
normalizer = 1.0 / total_weight
for i in range(bone_count):
bone_weight_array[count - i - 1] *= normalizer
oskin['bone_count_array'] = bone_count_array
oskin['bone_index_array'] = bone_index_array[:count]
oskin['bone_weight_array'] = bone_weight_array[:count]
# Bone constraints
for bone in armature.pose.bones:
if len(bone.constraints) > 0:
if 'constraints' not in oskin:
oskin['constraints'] = []
self.add_constraints(bone, oskin, bone=True)

View file

@ -5,118 +5,49 @@ import importlib
from bpy.app.handlers import persistent
import arm.utils
import arm.props as props
import arm.make as make
import arm.make_state as state
import arm.api
last_operator = None
first_update = True
v8_started = False
@persistent
def on_scene_update_pre(context):
# TODO: get rid of this function as soon as there is a proper way to detect object data updates
global last_operator
global first_update
global v8_started
if first_update == True: # Skip first one, object reports is_update_data
first_update = False
def on_depsgraph_update_post(self):
if state.proc_build != None:
return
# Viewport player
with_armory = bpy.context.scene.render.engine == 'ARMORY'
if with_armory:
play_area = None
if bpy.context.screen != None:
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
play_area = area
break
if play_area != None and play_area.spaces[0].shading.type == 'MATERIAL':
if not v8_started:
v8_started = True
make.build_viewport()
else:
v8_started = False
depsgraph = bpy.context.depsgraph
for update in depsgraph.updates:
uid = update.id
if hasattr(uid, 'arm_cached'):
# uid.arm_cached = False # TODO: does not trigger update
if isinstance(uid, bpy.types.Mesh):
bpy.data.meshes[uid.name].arm_cached = False
elif isinstance(uid, bpy.types.Curve):
bpy.data.curves[uid.name].arm_cached = False
elif isinstance(uid, bpy.types.MetaBall):
bpy.data.metaballs[uid.name].arm_cached = False
elif isinstance(uid, bpy.types.Armature):
bpy.data.armatures[uid.name].arm_cached = False
elif isinstance(uid, bpy.types.NodeTree):
bpy.data.node_groups[uid.name].arm_cached = False
elif isinstance(uid, bpy.types.Material):
bpy.data.materials[uid.name].arm_cached = False
if state.redraw_ui and bpy.context.screen != None:
for area in bpy.context.screen.areas:
def always():
if state.redraw_ui and context_screen != None:
for area in context_screen.areas:
if area.type == 'VIEW_3D' or area.type == 'PROPERTIES':
area.tag_redraw()
state.redraw_ui = False
# Recache edited data
ops = bpy.context.window_manager.operators
operators_changed = False
if len(ops) > 0 and last_operator != ops[-1]:
last_operator = ops[-1]
operators_changed = True
if hasattr(bpy.context, 'active_object'):
obj = bpy.context.active_object
if obj != None:
if obj.data != None and obj.data.is_updated:
recache(obj)
if len(ops) > 0 and ops[-1].bl_idname == 'OBJECT_OT_transform_apply':
recache(obj)
# New children
if obj.type == 'ARMATURE':
for c in obj.children:
if c.data != None and c.data.is_updated:
recache(c)
if hasattr(bpy.context, 'sculpt_object') and bpy.context.sculpt_object != None:
recache(bpy.context.sculpt_object)
if hasattr(bpy.context, 'active_pose_bone') and bpy.context.active_pose_bone != None:
recache(bpy.context.active_object)
if hasattr(bpy.context, 'object'):
obj = bpy.context.object
if obj != None:
if operators_changed:
op_changed(ops[-1], obj)
if obj.active_material != None and obj.active_material.is_updated:
if obj.active_material.lock_cache == True: # is_cached was set to true, resulting in a is_updated call
obj.active_material.lock_cache = False
else:
obj.active_material.is_cached = False
# Invalidate logic node tree cache if it is being edited..
space = arm.utils.logic_editor_space()
if space != None:
space.node_tree.is_cached = False
def recache(obj):
# Moving keyframes triggers is_updated_data..
if state.proc_build != None:
return
if obj.data == None:
return
if hasattr(obj.data, 'arm_cached'):
obj.data.arm_cached = False
def op_changed(op, obj):
# Recache mesh data
if op.bl_idname == 'OBJECT_OT_modifier_add' or \
op.bl_idname == 'OBJECT_OT_modifier_remove' or \
op.bl_idname == 'OBJECT_OT_transform_apply' or \
op.bl_idname == 'APPLY_OT_transformlocrotscale' or \
op.bl_idname == 'OBJECT_OT_shade_smooth' or \
op.bl_idname == 'OBJECT_OT_shade_flat':
# Note: Blender reverts object data when manipulating
# OBJECT_OT_transform_apply operator.. recaching object flag instead
obj.arm_cached = False
if op.bl_idname.startswith('MARKER_OT_'):
# Marker changed, recache action
obj.data.arm_cached = False
return 0.5
appended_py_paths = []
context_screen = None
@persistent
def on_load_post(context):
global appended_py_paths
global first_update
first_update = True
global context_screen
context_screen = bpy.context.screen
props.init_properties_on_load()
reload_blend_data()
@ -164,15 +95,17 @@ def load_library(asset_name):
ref.use_fake_user = True
def register():
if hasattr(bpy.app.handlers, 'scene_update_pre'):
bpy.app.handlers.scene_update_pre.append(on_scene_update_pre)
bpy.app.handlers.load_post.append(on_load_post)
bpy.app.handlers.depsgraph_update_post.append(on_depsgraph_update_post)
# bpy.app.handlers.undo_post.append(on_undo_post)
bpy.app.timers.register(always, persistent=True)
# TODO: On windows, on_load_post is not called when opening .blend file from explorer
if arm.utils.get_os() == 'win' and arm.utils.get_fp() != '':
on_load_post(None)
reload_blend_data()
def unregister():
if hasattr(bpy.app.handlers, 'scene_update_pre'):
bpy.app.handlers.scene_update_pre.remove(on_scene_update_pre)
bpy.app.handlers.load_post.remove(on_load_post)
bpy.app.handlers.depsgraph_update_post.remove(on_depsgraph_update_post)
# bpy.app.handlers.undo_post.remove(on_undo_post)

View file

@ -22,6 +22,7 @@
#
import struct
import io
import numpy as np
def _pack_integer(obj, fp):
if obj < 0:
@ -30,11 +31,11 @@ def _pack_integer(obj, fp):
elif obj >= -2**(8 - 1):
fp.write(b"\xd0" + struct.pack("b", obj))
elif obj >= -2**(16 - 1):
fp.write(b"\xd1" + struct.pack(">h", obj))
fp.write(b"\xd1" + struct.pack("<h", obj))
elif obj >= -2**(32 - 1):
fp.write(b"\xd2" + struct.pack(">i", obj))
fp.write(b"\xd2" + struct.pack("<i", obj))
elif obj >= -2**(64 - 1):
fp.write(b"\xd3" + struct.pack(">q", obj))
fp.write(b"\xd3" + struct.pack("<q", obj))
else:
raise Exception("huge signed int")
else:
@ -43,11 +44,11 @@ def _pack_integer(obj, fp):
elif obj <= 2**8 - 1:
fp.write(b"\xcc" + struct.pack("B", obj))
elif obj <= 2**16 - 1:
fp.write(b"\xcd" + struct.pack(">H", obj))
fp.write(b"\xcd" + struct.pack("<H", obj))
elif obj <= 2**32 - 1:
fp.write(b"\xce" + struct.pack(">I", obj))
fp.write(b"\xce" + struct.pack("<I", obj))
elif obj <= 2**64 - 1:
fp.write(b"\xcf" + struct.pack(">Q", obj))
fp.write(b"\xcf" + struct.pack("<Q", obj))
else:
raise Exception("huge unsigned int")
@ -59,8 +60,8 @@ def _pack_boolean(obj, fp):
def _pack_float(obj, fp):
# NOTE: forced 32-bit floats for Armory
# fp.write(b"\xcb" + struct.pack(">d", obj)) # Double
fp.write(b"\xca" + struct.pack(">f", obj))
# fp.write(b"\xcb" + struct.pack("<d", obj)) # Double
fp.write(b"\xca" + struct.pack("<f", obj))
def _pack_string(obj, fp):
obj = obj.encode('utf-8')
@ -69,9 +70,9 @@ def _pack_string(obj, fp):
elif len(obj) <= 2**8 - 1:
fp.write(b"\xd9" + struct.pack("B", len(obj)) + obj)
elif len(obj) <= 2**16 - 1:
fp.write(b"\xda" + struct.pack(">H", len(obj)) + obj)
fp.write(b"\xda" + struct.pack("<H", len(obj)) + obj)
elif len(obj) <= 2**32 - 1:
fp.write(b"\xdb" + struct.pack(">I", len(obj)) + obj)
fp.write(b"\xdb" + struct.pack("<I", len(obj)) + obj)
else:
raise Exception("huge string")
@ -79,9 +80,9 @@ def _pack_binary(obj, fp):
if len(obj) <= 2**8 - 1:
fp.write(b"\xc4" + struct.pack("B", len(obj)) + obj)
elif len(obj) <= 2**16 - 1:
fp.write(b"\xc5" + struct.pack(">H", len(obj)) + obj)
fp.write(b"\xc5" + struct.pack("<H", len(obj)) + obj)
elif len(obj) <= 2**32 - 1:
fp.write(b"\xc6" + struct.pack(">I", len(obj)) + obj)
fp.write(b"\xc6" + struct.pack("<I", len(obj)) + obj)
else:
raise Exception("huge binary string")
@ -89,22 +90,32 @@ def _pack_array(obj, fp):
if len(obj) <= 15:
fp.write(struct.pack("B", 0x90 | len(obj)))
elif len(obj) <= 2**16 - 1:
fp.write(b"\xdc" + struct.pack(">H", len(obj)))
fp.write(b"\xdc" + struct.pack("<H", len(obj)))
elif len(obj) <= 2**32 - 1:
fp.write(b"\xdd" + struct.pack(">I", len(obj)))
fp.write(b"\xdd" + struct.pack("<I", len(obj)))
else:
raise Exception("huge array")
# Float32
if len(obj) > 0 and isinstance(obj[0], float):
fp.write(b"\xca")
for e in obj:
fp.write(struct.pack(">f", e))
# Int32
fp.write(struct.pack("<f", e))
elif len(obj) > 0 and isinstance(obj[0], int):
fp.write(b"\xd2")
for e in obj:
fp.write(struct.pack(">i", e))
fp.write(struct.pack("<i", e))
# Float32
elif len(obj) > 0 and isinstance(obj[0], np.float32):
fp.write(b"\xca")
fp.write(obj.tobytes())
# Int32
elif len(obj) > 0 and isinstance(obj[0], np.int32):
fp.write(b"\xd2")
fp.write(obj.tobytes())
# Int16
elif len(obj) > 0 and isinstance(obj[0], np.int16):
fp.write(b"\xd1")
fp.write(obj.tobytes())
# Regular
else:
for e in obj:
@ -114,9 +125,9 @@ def _pack_map(obj, fp):
if len(obj) <= 15:
fp.write(struct.pack("B", 0x80 | len(obj)))
elif len(obj) <= 2**16 - 1:
fp.write(b"\xde" + struct.pack(">H", len(obj)))
fp.write(b"\xde" + struct.pack("<H", len(obj)))
elif len(obj) <= 2**32 - 1:
fp.write(b"\xdf" + struct.pack(">I", len(obj)))
fp.write(b"\xdf" + struct.pack("<I", len(obj)))
else:
raise Exception("huge array")
@ -137,7 +148,7 @@ def pack(obj, fp):
_pack_string(obj, fp)
elif isinstance(obj, bytes):
_pack_binary(obj, fp)
elif isinstance(obj, list) or isinstance(obj, tuple):
elif isinstance(obj, list) or isinstance(obj, tuple) or isinstance(obj, np.ndarray):
_pack_array(obj, fp)
elif isinstance(obj, dict):
_pack_map(obj, fp)

View file

@ -8,7 +8,7 @@ def parse_context(c, sres, asset, defs, vert=None, frag=None):
con['name'] = c['name']
con['constants'] = []
con['texture_units'] = []
con['vertex_structure'] = []
con['vertex_elements'] = []
# Names
con['vertex_shader'] = c['vertex_shader'].rsplit('.', 1)[0].split('/')[-1]
@ -77,13 +77,13 @@ def parse_context(c, sres, asset, defs, vert=None, frag=None):
def parse_shader(sres, c, con, defs, lines, parse_attributes):
skip_till_endif = 0
skip_else = False
vertex_structure_parsed = False
vertex_structure_parsing = False
vertex_elements_parsed = False
vertex_elements_parsing = False
stack = []
if parse_attributes == False:
vertex_structure_parsed = True
vertex_elements_parsed = True
for line in lines:
line = line.lstrip()
@ -116,15 +116,15 @@ def parse_shader(sres, c, con, defs, lines, parse_attributes):
if skip:
continue
if vertex_structure_parsed == False and line.startswith('in '):
vertex_structure_parsing = True
if vertex_elements_parsed == False and line.startswith('in '):
vertex_elements_parsing = True
vd = {}
s = line.split(' ')
vd['size'] = int(s[1][-1:])
vd['data'] = 'float' + s[1][-1:]
vd['name'] = s[2][:-1]
con['vertex_structure'].append(vd)
if vertex_structure_parsing == True and len(line) > 0 and line.startswith('//') == False and line.startswith('in ') == False:
vertex_structure_parsed = True
con['vertex_elements'].append(vd)
if vertex_elements_parsing == True and len(line) > 0 and line.startswith('//') == False and line.startswith('in ') == False:
vertex_elements_parsed = True
if line.startswith('uniform ') or line.startswith('//!uniform'): # Uniforms included from header files
s = line.split(' ')

View file

@ -7,7 +7,7 @@ class AddGroupNode(Node, ArmLogicTreeNode):
'''Add Group node'''
bl_idname = 'LNAddGroupNode'
bl_label = 'Add Group'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class AddTraitNode(Node, ArmLogicTreeNode):
'''Add trait node'''
bl_idname = 'LNAddTraitNode'
bl_label = 'Add Trait'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class AppendTransformNode(Node, ArmLogicTreeNode):
'''Append transform node'''
bl_idname = 'LNAppendTransformNode'
bl_label = 'Append Transform'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class CallFunctionNode(Node, ArmLogicTreeNode):
'''Call Haxe function node'''
bl_idname = 'LNCallFunctionNode'
bl_label = 'Call Function'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
min_inputs = 3
def __init__(self):

View file

@ -8,13 +8,13 @@ class CallGroupNode(Node, ArmLogicTreeNode):
'''Call group node'''
bl_idname = 'LNCallGroupNode'
bl_label = 'Call Node Group'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
@property
def property0(self):
return arm.utils.safesrc(bpy.data.worlds['Arm'].arm_project_package) + '.node.' + arm.utils.safesrc(self.property0_)
property0_ = StringProperty(name='Group', default='')
property0_: StringProperty(name='Group', default='')
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class ClearParentNode(Node, ArmLogicTreeNode):
'''Clear parent node'''
bl_idname = 'LNClearParentNode'
bl_label = 'Clear Parent'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class GroupOutputNode(Node, ArmLogicTreeNode):
'''Group output node'''
bl_idname = 'LNGroupOutputNode'
bl_label = 'Node Group Output'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class PauseTraitNode(Node, ArmLogicTreeNode):
'''Pause trait node'''
bl_idname = 'LNPauseTraitNode'
bl_label = 'Pause Trait'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class PrintNode(Node, ArmLogicTreeNode):
'''Print node'''
bl_idname = 'LNPrintNode'
bl_label = 'Print'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class RemoveActiveSceneNode(Node, ArmLogicTreeNode):
'''Remove active scene node'''
bl_idname = 'LNRemoveActiveSceneNode'
bl_label = 'Remove Active Scene'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class RemoveGroupNode(Node, ArmLogicTreeNode):
'''Remove Group node'''
bl_idname = 'LNRemoveGroupNode'
bl_label = 'Remove Group'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class RemoveObjectNode(Node, ArmLogicTreeNode):
'''Remove object node'''
bl_idname = 'LNRemoveObjectNode'
bl_label = 'Remove Object'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class RemoveTraitNode(Node, ArmLogicTreeNode):
'''Remove trait node'''
bl_idname = 'LNRemoveTraitNode'
bl_label = 'Remove Trait'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class ResumeTraitNode(Node, ArmLogicTreeNode):
'''Resume trait node'''
bl_idname = 'LNResumeTraitNode'
bl_label = 'Resume Trait'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class RotateObjectNode(Node, ArmLogicTreeNode):
'''Rotate object node'''
bl_idname = 'LNRotateObjectNode'
bl_label = 'Rotate Object'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class ScaleObjectNode(Node, ArmLogicTreeNode):
'''Scale object node'''
bl_idname = 'LNScaleObjectNode'
bl_label = 'Scale Object'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetCameraNode(Node, ArmLogicTreeNode):
'''Set camera node'''
bl_idname = 'LNSetCameraNode'
bl_label = 'Set Camera'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetCameraFovNode(Node, ArmLogicTreeNode):
'''Set camera FOV node'''
bl_idname = 'LNSetCameraFovNode'
bl_label = 'Set Camera FOV'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetLightColorNode(Node, ArmLogicTreeNode):
'''Set light color node'''
bl_idname = 'LNSetLightColorNode'
bl_label = 'Set Light Color'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetLightStrengthNode(Node, ArmLogicTreeNode):
'''Set light strength node'''
bl_idname = 'LNSetLightStrengthNode'
bl_label = 'Set Light Strength'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetLocationNode(Node, ArmLogicTreeNode):
'''Set location node'''
bl_idname = 'LNSetLocationNode'
bl_label = 'Set Location'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetMaterialNode(Node, ArmLogicTreeNode):
'''Set material node'''
bl_idname = 'LNSetMaterialNode'
bl_label = 'Set Material'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetMaterialImageParamNode(Node, ArmLogicTreeNode):
'''Set material image param node'''
bl_idname = 'LNSetMaterialImageParamNode'
bl_label = 'Set Material Image Param'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetMaterialRgbParamNode(Node, ArmLogicTreeNode):
'''Set material rgb param node'''
bl_idname = 'LNSetMaterialRgbParamNode'
bl_label = 'Set Material RGB Param'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetMaterialSlotNode(Node, ArmLogicTreeNode):
'''Set material slot node'''
bl_idname = 'LNSetMaterialSlotNode'
bl_label = 'Set Material Slot'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetMaterialValueParamNode(Node, ArmLogicTreeNode):
'''Set material value param node'''
bl_idname = 'LNSetMaterialValueParamNode'
bl_label = 'Set Material Value Param'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetMeshNode(Node, ArmLogicTreeNode):
'''Set mesh node'''
bl_idname = 'LNSetMeshNode'
bl_label = 'Set Mesh'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetNameNode(Node, ArmLogicTreeNode):
'''Set name node'''
bl_idname = 'LNSetNameNode'
bl_label = 'Set Name'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetParentNode(Node, ArmLogicTreeNode):
'''Set parent node'''
bl_idname = 'LNSetParentNode'
bl_label = 'Set Parent'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetParentBoneNode(Node, ArmLogicTreeNode):
'''Set parent bone node'''
bl_idname = 'LNSetParentBoneNode'
bl_label = 'Set Parent Bone'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetPropertyNode(Node, ArmLogicTreeNode):
'''Set property node'''
bl_idname = 'LNSetPropertyNode'
bl_label = 'Set Property'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetRotationNode(Node, ArmLogicTreeNode):
'''Set rotation node'''
bl_idname = 'LNSetRotationNode'
bl_label = 'Set Rotation'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetScaleNode(Node, ArmLogicTreeNode):
'''Set scale node'''
bl_idname = 'LNSetScaleNode'
bl_label = 'Set Scale'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetSceneNode(Node, ArmLogicTreeNode):
'''Set scene node'''
bl_idname = 'LNSetSceneNode'
bl_label = 'Set Scene'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetTimeScaleNode(Node, ArmLogicTreeNode):
'''Set time scale node'''
bl_idname = 'LNSetTimeScaleNode'
bl_label = 'Set Time Scale'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetTransformNode(Node, ArmLogicTreeNode):
'''Set transform node'''
bl_idname = 'LNSetTransformNode'
bl_label = 'Set Transform'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetVariableNode(Node, ArmLogicTreeNode):
'''Set variable node'''
bl_idname = 'LNSetVariableNode'
bl_label = 'Set Variable'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetVisibleNode(Node, ArmLogicTreeNode):
'''Set visible node'''
bl_idname = 'LNSetVisibleNode'
bl_label = 'Set Visible'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SleepNode(Node, ArmLogicTreeNode):
'''Sleep node'''
bl_idname = 'LNSleepNode'
bl_label = 'Sleep'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SpawnObjectNode(Node, ArmLogicTreeNode):
'''Spawn object node'''
bl_idname = 'LNSpawnObjectNode'
bl_label = 'Spawn Object'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SpawnSceneNode(Node, ArmLogicTreeNode):
'''Spawn scene node'''
bl_idname = 'LNSpawnSceneNode'
bl_label = 'Spawn Scene'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class TranslateObjectNode(Node, ArmLogicTreeNode):
'''Translate object node'''
bl_idname = 'LNTranslateObjectNode'
bl_label = 'Translate Object'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -8,7 +8,7 @@ class TranslateOnLocalAxisNode(Node, ArmLogicTreeNode):
'''TranslateOnLocalAxisNode'''
bl_idname = 'LNTranslateOnLocalAxisNode'
bl_label = 'Translate On Local Axis'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class WriteStorageNode(Node, ArmLogicTreeNode):
'''WriteStorage node'''
bl_idname = 'LNWriteStorageNode'
bl_label = 'Write Storage'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class AnimationStateNode(Node, ArmLogicTreeNode):
'''Animation state node'''
bl_idname = 'LNAnimationStateNode'
bl_label = 'Animation State'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketObject', 'Object')

View file

@ -7,7 +7,7 @@ class BlendActionNode(Node, ArmLogicTreeNode):
'''Blend action node'''
bl_idname = 'LNBlendActionNode'
bl_label = 'Blend Action'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class BoneFKNode(Node, ArmLogicTreeNode):
'''Bone Forward Kinematics node'''
bl_idname = 'LNBoneFKNode'
bl_label = 'Bone FK'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class BoneIKNode(Node, ArmLogicTreeNode):
'''Bone Inverse Kinematics node'''
bl_idname = 'LNBoneIKNode'
bl_label = 'Bone IK'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class OnActionMarkerNode(Node, ArmLogicTreeNode):
'''On action marker node'''
bl_idname = 'LNOnActionMarkerNode'
bl_label = 'On Action Marker'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketObject', 'Object')

View file

@ -7,7 +7,7 @@ class PauseActionNode(Node, ArmLogicTreeNode):
'''Pause action node'''
bl_idname = 'LNPauseActionNode'
bl_label = 'Pause Action'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class PauseTilesheetNode(Node, ArmLogicTreeNode):
'''Pause tilesheet node'''
bl_idname = 'LNPauseTilesheetNode'
bl_label = 'Pause Tilesheet'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class PlayActionNode(Node, ArmLogicTreeNode):
'''Play action node'''
bl_idname = 'LNPlayActionNode'
bl_label = 'Play Action'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class PlayTilesheetNode(Node, ArmLogicTreeNode):
'''Play tilesheet node'''
bl_idname = 'LNPlayTilesheetNode'
bl_label = 'Play Tilesheet'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class ResumeActionNode(Node, ArmLogicTreeNode):
'''Resume action node'''
bl_idname = 'LNResumeActionNode'
bl_label = 'Resume Action'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class ResumeTilesheetNode(Node, ArmLogicTreeNode):
'''Resume tilesheet node'''
bl_idname = 'LNResumeTilesheetNode'
bl_label = 'Resume Tilesheet'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetActionSpeedNode(Node, ArmLogicTreeNode):
'''Set action speed node'''
bl_idname = 'LNSetActionSpeedNode'
bl_label = 'Set Action Speed'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class SetParticleSpeedNode(Node, ArmLogicTreeNode):
'''Set particle speed node'''
bl_idname = 'LNSetParticleSpeedNode'
bl_label = 'Set Particle Speed'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -37,7 +37,7 @@ class ArmArraySocket(bpy.types.NodeSocket):
class ArmObjectSocket(bpy.types.NodeSocket):
bl_idname = 'ArmNodeSocketObject'
bl_label = 'Object Socket'
default_value = StringProperty(name='Object', default='')
default_value: StringProperty(name='Object', default='')
def get_default_value(self):
if self.default_value == '':
@ -70,7 +70,7 @@ class ArmNodeEyedropButton(bpy.types.Operator):
'''Pick selected object'''
bl_idname = 'arm.node_eyedrop'
bl_label = 'Eyedrop'
socket_index = StringProperty(name='Socket Index', default='')
socket_index: StringProperty(name='Socket Index', default='')
def execute(self, context):
global object_sockets
@ -82,7 +82,7 @@ class ArmNodeEyedropButton(bpy.types.Operator):
class ArmAnimActionSocket(bpy.types.NodeSocket):
bl_idname = 'ArmNodeSocketAnimAction'
bl_label = 'Action Socket'
default_value = StringProperty(name='Action', default='')
default_value: StringProperty(name='Action', default='')
def get_default_value(self):
if self.default_value == '':
@ -107,10 +107,10 @@ class ArmNodeAddInputButton(bpy.types.Operator):
'''Add new input'''
bl_idname = 'arm.node_add_input'
bl_label = 'Add Input'
node_index = StringProperty(name='Node Index', default='')
socket_type = StringProperty(name='Socket Type', default='NodeSocketShader')
name_format = StringProperty(name='Name Format', default='Input {0}')
index_name_offset = IntProperty(name='Index Name Offset', default=0)
node_index: StringProperty(name='Node Index', default='')
socket_type: StringProperty(name='Socket Type', default='NodeSocketShader')
name_format: StringProperty(name='Name Format', default='Input {0}')
index_name_offset: IntProperty(name='Index Name Offset', default=0)
def execute(self, context):
global array_nodes
@ -122,8 +122,8 @@ class ArmNodeAddInputValueButton(bpy.types.Operator):
'''Add new input'''
bl_idname = 'arm.node_add_input_value'
bl_label = 'Add Input'
node_index = StringProperty(name='Node Index', default='')
socket_type = StringProperty(name='Socket Type', default='NodeSocketShader')
node_index: StringProperty(name='Node Index', default='')
socket_type: StringProperty(name='Socket Type', default='NodeSocketShader')
def execute(self, context):
global array_nodes
@ -135,7 +135,7 @@ class ArmNodeRemoveInputButton(bpy.types.Operator):
'''Remove last input'''
bl_idname = 'arm.node_remove_input'
bl_label = 'Remove Input'
node_index = StringProperty(name='Node Index', default='')
node_index: StringProperty(name='Node Index', default='')
def execute(self, context):
global array_nodes
@ -150,7 +150,7 @@ class ArmNodeRemoveInputValueButton(bpy.types.Operator):
'''Remove last input'''
bl_idname = 'arm.node_remove_input_value'
bl_label = 'Remove Input'
node_index = StringProperty(name='Node Index', default='')
node_index: StringProperty(name='Node Index', default='')
def execute(self, context):
global array_nodes
@ -165,10 +165,10 @@ class ArmNodeAddOutputButton(bpy.types.Operator):
'''Add new output'''
bl_idname = 'arm.node_add_output'
bl_label = 'Add Output'
node_index = StringProperty(name='Node Index', default='')
socket_type = StringProperty(name='Socket Type', default='NodeSocketShader')
name_format = StringProperty(name='Name Format', default='Output {0}')
index_name_offset = IntProperty(name='Index Name Offset', default=0)
node_index: StringProperty(name='Node Index', default='')
socket_type: StringProperty(name='Socket Type', default='NodeSocketShader')
name_format: StringProperty(name='Name Format', default='Output {0}')
index_name_offset: IntProperty(name='Index Name Offset', default=0)
def execute(self, context):
global array_nodes
@ -180,7 +180,7 @@ class ArmNodeRemoveOutputButton(bpy.types.Operator):
'''Remove last output'''
bl_idname = 'arm.node_remove_output'
bl_label = 'Remove Output'
node_index = StringProperty(name='Node Index', default='')
node_index: StringProperty(name='Node Index', default='')
def execute(self, context):
global array_nodes
@ -195,12 +195,12 @@ class ArmNodeAddInputOutputButton(bpy.types.Operator):
'''Add new input and output'''
bl_idname = 'arm.node_add_input_output'
bl_label = 'Add Input Output'
node_index = StringProperty(name='Node Index', default='')
in_socket_type = StringProperty(name='In Socket Type', default='NodeSocketShader')
out_socket_type = StringProperty(name='Out Socket Type', default='NodeSocketShader')
in_name_format = StringProperty(name='In Name Format', default='Input {0}')
out_name_format = StringProperty(name='Out Name Format', default='Output {0}')
in_index_name_offset = IntProperty(name='Index Name Offset', default=0)
node_index: StringProperty(name='Node Index', default='')
in_socket_type: StringProperty(name='In Socket Type', default='NodeSocketShader')
out_socket_type: StringProperty(name='Out Socket Type', default='NodeSocketShader')
in_name_format: StringProperty(name='In Name Format', default='Input {0}')
out_name_format: StringProperty(name='Out Name Format', default='Output {0}')
in_index_name_offset: IntProperty(name='Index Name Offset', default=0)
def execute(self, context):
global array_nodes
@ -215,7 +215,7 @@ class ArmNodeRemoveInputOutputButton(bpy.types.Operator):
'''Remove last input and output'''
bl_idname = 'arm.node_remove_input_output'
bl_label = 'Remove Input Output'
node_index = StringProperty(name='Node Index', default='')
node_index: StringProperty(name='Node Index', default='')
def execute(self, context):
global array_nodes

View file

@ -7,7 +7,7 @@ class ArrayAddNode(Node, ArmLogicTreeNode):
'''Array add node'''
bl_idname = 'LNArrayAddNode'
bl_label = 'Array Add'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def __init__(self):
array_nodes[str(id(self))] = self

View file

@ -7,7 +7,7 @@ class ArrayAddUniqueNode(Node, ArmLogicTreeNode):
'''Array add unique node'''
bl_idname = 'LNArrayAddUniqueNode'
bl_label = 'Array Add Unique'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def __init__(self):
array_nodes[str(id(self))] = self

View file

@ -7,7 +7,7 @@ class ArrayGetNode(Node, ArmLogicTreeNode):
'''Array get node'''
bl_idname = 'LNArrayGetNode'
bl_label = 'Array Get'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketArray', 'Array')

View file

@ -7,7 +7,7 @@ class ArrayLengthNode(Node, ArmLogicTreeNode):
'''Array length node'''
bl_idname = 'LNArrayLengthNode'
bl_label = 'Array Length'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketArray', 'Array')

View file

@ -7,7 +7,7 @@ class ArrayPopNode(Node, ArmLogicTreeNode):
'''Array pop node'''
bl_idname = 'LNArrayPopNode'
bl_label = 'Array Pop'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketArray', 'Array')

View file

@ -7,7 +7,7 @@ class ArrayRemoveNode(Node, ArmLogicTreeNode):
'''Array remove node'''
bl_idname = 'LNArrayRemoveNode'
bl_label = 'Array Remove'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

View file

@ -7,7 +7,7 @@ class ArrayRemoveValueNode(Node, ArmLogicTreeNode):
'''Array remove value node'''
bl_idname = 'LNArrayRemoveValueNode'
bl_label = 'Array Remove Value'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
# def __init__(self):
# array_nodes[str(id(self))] = self

View file

@ -7,7 +7,7 @@ class ArraySetNode(Node, ArmLogicTreeNode):
'''Array set node'''
bl_idname = 'LNArraySetNode'
bl_label = 'Array Set'
bl_icon = 'GAME'
bl_icon = 'QUESTION'
def init(self, context):
self.inputs.new('ArmNodeSocketAction', 'In')

Some files were not shown because too many files have changed in this diff Show more