DebugDraw class uses a plane to draw a line: it’s creepy !
I would draw a line with 2D API. But I don’t understand the “World To Screen Coords” logic Node :
override function get(from:Int):Dynamic {
var v1:Vec4 = inputs[0].get();
if (v1 == null) return null;
var cam = iron.Scene.active.camera;
v.setFrom(v1);
v.applyproj(cam.V);
v.applyproj(cam.P);
return v;
}
I found a topic about “Screen to World” and so I try this :
public function WorldToScreen(loc:Vec4):Vec2 {
var v = new Vec4();
var cam = iron.Scene.active.camera;
v.setFrom(loc);
v.applyproj(cam.V);
v.applyproj(cam.P);
var w = kha.System.windowWidth();
var h = kha.System.windowHeight();
return new Vec2((v.x*w+0.5)/2, (v.y*h-0.5)/-2);
}
It’s much better, but it’s bad. How to use “World To Screen Coords” correctly to draw a overlay.
Camera plan To Screen :
x’ = xw/2 + w/2 = w/2 * (x+1)
y’= -yh/2 + h/2 = h/2*(-y+1)
implementation
public function WorldToScreen(loc:Vec4):Vec2 {
var v = new Vec4();
var cam = iron.Scene.active.camera;
if (cam != null) {
v.setFrom(loc);
v.applyproj(cam.V);
v.applyproj(cam.P);
}
var w = kha.System.windowWidth();
var h = kha.System.windowHeight();
return new Vec2(v.x*0.5 * w + w*0.5, -v.y*0.5 * h + h * 0.5);
}
package arm;
#if arm_debug
import iron.math.Vec2;
import kha.Color;
import kha.System;
import iron.math.Vec4;
class LineDebug {
public var a:Vec4 = null;
public var b:Vec4 = null;
public var color:kha.Color = 0xffff0000;
public var strength : Float = 1;
public function new() {}
}
interface IDebug {
public function addLine(a:Vec4, b:Vec4, color:Color, strength:Float):Void;
}
class VisualDebugTrait extends iron.Trait implements IDebug {
private var lines:Array<LineDebug> = new Array<LineDebug>();
public static var instance : IDebug;
public function new() {
super();
this.notifyOnRender2D(this.onRender);
VisualDebugTrait.instance = this;
}
public function addLine(a:Vec4, b:Vec4, color:Color, strength:Float) {
var line = new LineDebug();
line.a = a;
line.b = b;
line.color = color;
line.strength = strength;
this.lines.push(line);
}
/**
* World To Screen Coords
* thread http://forums.armory3d.org/t/worldtoscreencoord-draw-debug-lines-with-2d-api/3467
* @param loc
* @return Vec2
*/
public function WorldToScreen(loc:Vec4):Vec2 {
var v = new Vec4();
var cam = iron.Scene.active.camera;
if (cam != null) {
v.setFrom(loc);
v.applyproj(cam.V);
v.applyproj(cam.P);
}
var w = System.windowWidth();
var h = System.windowHeight();
return new Vec2((v.x + 1) * 0.5 * w, (-v.y + 1) * 0.5 * h);
}
public function onRender(g:kha.graphics2.Graphics) {
while (this.lines.length > 0) {
var line = this.lines.pop();
var aScreen = WorldToScreen(line.a);
var bScreen = WorldToScreen(line.b);
g.color = line.color;
g.drawLine(aScreen.x, aScreen.y, bScreen.x, bScreen.y,line.strength);
}
}
}
#end
So, did you find a way to implement this on the SDK?
Can the debugDraw.hx be expanded to include this functionality, to replace the current implementation of line drawing?
It’s not baked, I have an issue : lines are projected from the front and back of camera… I have to compute an intersection betwen the segment and the camera plan to fix it correctly.
And I’m not sure to release on the SDK.
My VDebug works like a logger. You write your “log” anywhere. It’s very different from the current debug system.
Hi @Marc , so did you find a solution to that problem yet?
On a different note: I’m currently evaluating different ways to draw lines in Armory to add support for grease pencil objects back to the engine, and I found that your solution works and is simple enough , although still there are a few things that prevent me from just going with it: first is that one you mentioned about back projection, other is no anti-aliasing and last one I found is inconsistent line size depending on distance.
so, my question is: do you know if it’s possible to fix this drawing solution to make it work for such a feature? or should another solution be used for the task?
So I am trying to track a 3D object with a 2D element and I can’t get it to work correctly. I am trying to work with Marcs WorldToScree function, something like this here:
var my3dObjectPos = object.transform.loc;
var toScreen = WorldToScreen(my3dObjectPos);
var element2d = canvas.getElement("my2Dthing");
element2D.x = toScreen.x;
element2d.y = toScreen.y;
function WorldToScreen(loc:Vec4):Vec2 {
var v = new Vec4();
var cam = iron.Scene.active.camera;
if (cam != null) {
v.setFrom(loc);
v.applyproj(cam.V);
v.applyproj(cam.P);
}
var w = App.w(); // var w = System.windowWidth();
var h = App.h(); // var h = System.windowHeight();
return new Vec2((v.x + 1) * 0.5 * w, (-v.y + 1) * 0.5 * h);
}
I also tried this with nodes, but that didn’t work at all. Any ideas? I can’t imagine this to be that difficult. I guess I just think wrong here?