Begin projection layer

This commit is contained in:
Lubos Lenco
2020-06-09 18:28:46 +02:00
parent c39588db00
commit 2b9d415f16
9 changed files with 204 additions and 105 deletions
+1
View File
@@ -131,6 +131,7 @@ class Context {
public static var axisY = false;
public static var axisZ = false;
public static var axisStart = 0.0;
public static var axisLoc = 0.0;
public static var brushNodesRadius = 1.0;
public static var brushNodesOpacity = 1.0;
+31 -2
View File
@@ -393,7 +393,6 @@ class Layers {
UIHeader.inst.worktab.position = SpaceMaterial;
if (current != null) current.begin(false);
return;
}
@@ -412,8 +411,13 @@ class Layers {
setObjectMask();
if (first) {
first = false;
MaterialParser.parsePaintMaterial();
first = false;
}
// Decal layer
if (l.uvType == UVProject) {
l.clearLayer();
}
for (i in 0...fills) {
@@ -434,6 +438,31 @@ class Layers {
}
}
public static function updateFillLayer(fills = 1) {
var current = @:privateAccess kha.graphics4.Graphics2.current;
if (current != null) current.end();
var selectedTool = Context.tool;
Context.pdirty = fills;
Context.layerIsMask = false;
Context.tool = ToolFill;
// Decal layer
if (Context.layer.uvType == UVProject) {
Context.layer.clearLayer();
}
MaterialParser.parsePaintMaterial();
for (i in 0...fills) {
RenderPathPaint.commandsPaint();
}
Context.rdirty = 2;
Context.tool = selectedTool;
if (current != null) current.begin(false);
}
public static function setObjectMask() {
var ar = ["None"];
for (p in Project.paintObjects) ar.push(p.name);
+4
View File
@@ -43,6 +43,10 @@ class LayerSlot {
public var paintEmis = true;
public var paintSubs = true;
public var projectX = 0.0; // Decal layer
public var projectY = 0.0;
public var projectZ = 0.0;
var createMaskColor: Int;
var createMaskImage: Image;
+8 -1
View File
@@ -76,7 +76,14 @@ class MakePaint {
vert.write('gl_Position = vec4(tpos, 0.0, 1.0);');
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix');
var decalLayer = Context.layer.material_mask != null && Context.layer.uvType == UVProject;
if (decalLayer) {
vert.add_uniform('mat4 WVP', '_decalLayerMatrix');
}
else {
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix');
}
vert.add_out('vec4 ndc');
vert.write_attrib('ndc = mul(vec4(pos.xyz, 1.0), WVP);');
+8 -2
View File
@@ -8,7 +8,8 @@ class MakeTexcoord {
public static function run(vert: MaterialShader, frag: MaterialShader) {
var uvType = Context.layer.material_mask != null ? Context.layer.uvType : Context.brushPaint;
var fillLayer = Context.layer.material_mask != null;
var uvType = fillLayer ? Context.layer.uvType : Context.brushPaint;
var decal = Context.tool == ToolDecal || Context.tool == ToolText;
// TexCoords - project
@@ -16,7 +17,12 @@ class MakeTexcoord {
frag.add_uniform('float brushScale', '_brushScale');
frag.write_attrib('vec2 uvsp = sp.xy;');
if (decal) {
if (fillLayer) { // Decal layer
frag.write_attrib('uvsp.x *= aspectRatio;');
frag.write_attrib('uvsp.xy *= 4.0;');
//frag.write_attrib('if (uvsp.x < 0.0 || uvsp.y < 0.0 || uvsp.x > 1.0 || uvsp.y > 1.0) discard;');
}
else if (decal) {
frag.write_attrib('uvsp -= inp.xy;');
frag.write_attrib('uvsp.x *= aspectRatio;');
frag.write_attrib('uvsp *= 0.21 / (brushRadius * 0.9);');
+134 -93
View File
@@ -7,91 +7,141 @@ import iron.math.RayCaster;
import iron.math.Vec4;
import iron.Scene;
import arm.ui.UISidebar;
import arm.ui.UIHeader;
import arm.Enums;
class Gizmo {
public static function update() {
var gizmo = Context.gizmo;
if (!gizmo.visible) return;
static var v = new Vec4();
if (Context.object != null) {
var cam = Scene.active.camera;
gizmo.transform.loc.setFrom(Context.object.transform.loc);
var dist = Vec4.distance(cam.transform.loc, gizmo.transform.loc) / 10;
gizmo.transform.scale.set(dist, dist, dist);
Context.gizmoX.transform.scale.set(dist, dist, dist);
Context.gizmoY.transform.scale.set(dist, dist, dist);
Context.gizmoZ.transform.scale.set(dist, dist, dist);
gizmo.transform.buildMatrix();
}
public static function update() {
var isRender = UIHeader.inst.worktab.position == SpaceRender;
var isPaint = UIHeader.inst.worktab.position == SpacePaint;
var isObject = isRender && Context.object != null;
var isDecal = isPaint && Context.layer.material_mask != null && Context.layer.uvType == UVProject;
var gizmo = Context.gizmo;
gizmo.visible = isObject || isDecal;
if (!gizmo.visible) return;
var mouse = Input.getMouse();
var kb = Input.getKeyboard();
if (mouse.viewX < App.w()) {
if (kb.started("delete") || kb.started("backspace")) {
if (Context.object != null) {
Context.object.remove();
Context.selectObject(Scene.active.getChild("Scene"));
if (isObject) {
gizmo.transform.loc.setFrom(Context.object.transform.loc);
}
else if (isDecal) {
gizmo.transform.loc.set(Context.layer.projectX, Context.layer.projectY, Context.layer.projectZ);
}
var cam = Scene.active.camera;
var dist = Vec4.distance(cam.transform.loc, gizmo.transform.loc) / 10;
gizmo.transform.scale.set(dist, dist, dist);
Context.gizmoX.transform.scale.set(dist, dist, dist);
Context.gizmoY.transform.scale.set(dist, dist, dist);
Context.gizmoZ.transform.scale.set(dist, dist, dist);
gizmo.transform.buildMatrix();
// Scene control
if (isObject) {
if (mouse.viewX < App.w()) {
if (kb.started("delete") || kb.started("backspace")) {
if (Context.object != null) {
Context.object.remove();
Context.selectObject(Scene.active.getChild("Scene"));
}
}
if (kb.started("c") && Context.object != null) {
if (Std.is(Context.object, MeshObject)) {
var mo = cast(Context.object, MeshObject);
var object = Scene.active.addMeshObject(mo.data, mo.materials, Scene.active.getChild("Scene"));
object.name = mo.name + ".1";
object.transform.loc.setFrom(mo.transform.loc);
object.transform.rot.setFrom(mo.transform.rot);
object.transform.scale.setFrom(mo.transform.scale);
var hit = RayCaster.planeIntersect(Vec4.zAxis(), new Vec4(), mouse.viewX, mouse.viewY, Scene.active.camera);
if (hit != null) {
object.transform.loc.x = hit.x;
object.transform.loc.y = hit.y;
object.transform.setRotation(0, 0, Math.random() * 3.1516 * 2);
}
object.transform.buildMatrix();
for (t in mo.traits) { // Clone traits
var trait = Type.createInstance(Type.getClass(t), []);
object.addTrait(trait);
}
Context.selectObject(object);
}
else if (Std.is(Context.object, LightObject)) {
var lo = cast(Context.object, LightObject);
var object = Scene.active.addLightObject(lo.data, Scene.active.getChild("Scene"));
object.name = lo.name + ".1";
object.transform.loc.setFrom(lo.transform.loc);
object.transform.rot.setFrom(lo.transform.rot);
object.transform.scale.setFrom(lo.transform.scale);
object.transform.buildMatrix();
Context.selectObject(object);
}
Context.rdirty = 3;
Context.ddirty = 3;
}
if (kb.started("m")) { // skip voxel
var raw = Context.materialScene.data.raw;
raw.skip_context = raw.skip_context == "" ? "voxel" : "";
}
}
if (kb.started("c") && Context.object != null) {
if (Std.is(Context.object, MeshObject)) {
var mo = cast(Context.object, MeshObject);
var object = Scene.active.addMeshObject(mo.data, mo.materials, Scene.active.getChild("Scene"));
object.name = mo.name + ".1";
object.transform.loc.setFrom(mo.transform.loc);
object.transform.rot.setFrom(mo.transform.rot);
object.transform.scale.setFrom(mo.transform.scale);
var hit = RayCaster.planeIntersect(Vec4.zAxis(), new Vec4(), mouse.viewX, mouse.viewY, Scene.active.camera);
if (hit != null) {
object.transform.loc.x = hit.x;
object.transform.loc.y = hit.y;
object.transform.setRotation(0, 0, Math.random() * 3.1516 * 2);
}
object.transform.buildMatrix();
for (t in mo.traits) { // Clone traits
var trait = Type.createInstance(Type.getClass(t), []);
object.addTrait(trait);
}
Context.selectObject(object);
}
else if (Std.is(Context.object, LightObject)) {
var lo = cast(Context.object, LightObject);
var object = Scene.active.addLightObject(lo.data, Scene.active.getChild("Scene"));
object.name = lo.name + ".1";
object.transform.loc.setFrom(lo.transform.loc);
object.transform.rot.setFrom(lo.transform.rot);
object.transform.scale.setFrom(lo.transform.scale);
object.transform.buildMatrix();
Context.selectObject(object);
}
Context.rdirty = 3;
Context.ddirty = 3;
if (mouse.started("middle")) {
#if arm_physics
var physics = arm.plugin.PhysicsWorld.active;
var pb = physics.pickClosest(mouse.viewX, mouse.viewY);
if (pb != null) Context.selectObject(pb.object);
#end
}
if (kb.started("m")) { // skip voxel
var raw = Context.materialScene.data.raw;
raw.skip_context = raw.skip_context == "" ? "voxel" : "";
if (Context.axisX || Context.axisY || Context.axisZ) {
if (Context.axisX) {
Context.object.transform.loc.x = Context.axisLoc;
}
else if (Context.axisY) {
Context.object.transform.loc.y = Context.axisLoc;
}
else if (Context.axisZ) {
Context.object.transform.loc.z = Context.axisLoc;
}
Context.object.transform.buildMatrix();
#if arm_physics
var pb = Context.object.getTrait(arm.plugin.PhysicsBody);
if (pb != null) pb.syncTransform();
#end
}
}
// Decal layer control
else if (isDecal) {
if (Context.axisX || Context.axisY || Context.axisZ) {
if (Context.axisX) {
Context.layer.projectX = Context.axisLoc;
}
else if (Context.axisY) {
Context.layer.projectY = Context.axisLoc;
}
else if (Context.axisZ) {
Context.layer.projectZ = Context.axisLoc;
}
Layers.updateFillLayer();
}
}
if (mouse.started("middle")) {
#if arm_physics
var physics = arm.plugin.PhysicsWorld.active;
var pb = physics.pickClosest(mouse.viewX, mouse.viewY);
if (pb != null) Context.selectObject(pb.object);
#end
}
// Axis movement
if (mouse.started("left") && Context.object.name != "Scene") {
gizmo.transform.buildMatrix();
var trs = [Context.gizmoX.transform, Context.gizmoY.transform, Context.gizmoZ.transform];
var hit = RayCaster.closestBoxIntersect(trs, mouse.viewX, mouse.viewY, Scene.active.camera);
if (hit != null) {
@@ -106,44 +156,35 @@ class Gizmo {
}
if (Context.axisX || Context.axisY || Context.axisZ) {
var t = Context.object.transform;
var v = new Vec4();
v.set(t.worldx(), t.worldy(), t.worldz());
Context.rdirty = 2;
if (isObject) {
var t = Context.object.transform;
v.set(t.worldx(), t.worldy(), t.worldz());
}
else if (isDecal) {
v.set(Context.layer.projectX, Context.layer.projectY, Context.layer.projectZ);
}
if (Context.axisX) {
var hit = RayCaster.planeIntersect(Vec4.yAxis(), v, mouse.viewX, mouse.viewY, Scene.active.camera);
if (hit != null) {
if (Context.axisStart == 0) Context.axisStart = hit.x - Context.object.transform.loc.x;
Context.object.transform.loc.x = hit.x - Context.axisStart;
Context.object.transform.buildMatrix();
#if arm_physics
var pb = Context.object.getTrait(arm.plugin.PhysicsBody);
if (pb != null) pb.syncTransform();
#end
if (Context.axisStart == 0) Context.axisStart = hit.x - v.x;
Context.axisLoc = hit.x - Context.axisStart;
}
}
else if (Context.axisY) {
var hit = RayCaster.planeIntersect(Vec4.xAxis(), v, mouse.viewX, mouse.viewY, Scene.active.camera);
if (hit != null) {
if (Context.axisStart == 0) Context.axisStart = hit.y - Context.object.transform.loc.y;
Context.object.transform.loc.y = hit.y - Context.axisStart;
Context.object.transform.buildMatrix();
#if arm_physics
var pb = Context.object.getTrait(arm.plugin.PhysicsBody);
if (pb != null) pb.syncTransform();
#end
if (Context.axisStart == 0) Context.axisStart = hit.y - v.y;
Context.axisLoc = hit.y - Context.axisStart;
}
}
else if (Context.axisZ) {
var hit = RayCaster.planeIntersect(Vec4.xAxis(), v, mouse.viewX, mouse.viewY, Scene.active.camera);
if (hit != null) {
if (Context.axisStart == 0) Context.axisStart = hit.z - Context.object.transform.loc.z;
Context.object.transform.loc.z = hit.z - Context.axisStart;
Context.object.transform.buildMatrix();
#if arm_physics
var pb = Context.object.getTrait(arm.plugin.PhysicsBody);
if (pb != null) pb.syncTransform();
#end
if (Context.axisStart == 0) Context.axisStart = hit.z - v.z;
Context.axisLoc = hit.z - Context.axisStart;
}
}
}
+16
View File
@@ -4,6 +4,7 @@ import iron.data.MaterialData;
import iron.object.Object;
import iron.system.Input;
import iron.math.Vec4;
import iron.math.Mat4;
import iron.RenderPath;
import iron.Scene;
#if arm_painter
@@ -21,6 +22,7 @@ class Uniforms {
iron.object.Uniforms.externalVec2Links = [linkVec2];
iron.object.Uniforms.externalVec3Links = [linkVec3];
iron.object.Uniforms.externalVec4Links = [linkVec4];
iron.object.Uniforms.externalMat4Links = [linkMat4];
iron.object.Uniforms.externalTextureLinks = [linkTex];
}
@@ -327,6 +329,20 @@ class Uniforms {
return null;
}
public static function linkMat4(object: Object, mat: MaterialData, link: String): iron.math.Mat4 {
if (link == "_decalLayerMatrix") { // Decal layer
var camera = Scene.active.camera;
var m = iron.object.Uniforms.helpMat;
m.setFrom(object.transform.worldUnpack);
var V = Mat4.identity();
V.setLookAt(new Vec4(Context.layer.projectX, -5, Context.layer.projectZ), new Vec4(Context.layer.projectX, 0, Context.layer.projectZ), new Vec4(0, 0, 1));
m.multmat(V);
m.multmat(camera.P);
return m;
}
return null;
}
public static function linkTex(object: Object, mat: MaterialData, link: String): kha.Image {
#if arm_painter
if (link == "_texcolorid") {
+1 -1
View File
@@ -629,7 +629,7 @@ class TabLayers {
var uvTypeHandle = Id.handle().nest(l.id);
uvTypeHandle.position = l.uvType;
l.uvType = ui.combo(uvTypeHandle, [tr("UV Map"), tr("Triplanar")], tr("TexCoord"));
l.uvType = ui.combo(uvTypeHandle, [tr("UV Map"), tr("Triplanar"), tr("Project")], tr("TexCoord"));
if (uvTypeHandle.changed) {
Context.setMaterial(l.material_mask);
Context.setLayer(l);
+1 -6
View File
@@ -648,9 +648,7 @@ class UISidebar {
if (undoPressed) History.undo();
else if (redoPressed) History.redo();
if (UIHeader.inst.worktab.position == SpaceRender) {
arm.plugin.Gizmo.update();
}
arm.plugin.Gizmo.update();
if (Context.lastCombo != null || (ui.tooltipImg == null && Context.lastTooltip != null)) App.redrawUI();
Context.lastCombo = ui.comboSelectedHandle;
@@ -677,7 +675,6 @@ class UISidebar {
if (tabh == 0) {
tabh = tabh1 = tabh2 = Std.int(System.windowHeight() / 3);
}
Context.gizmo.visible = false;
if (ui.window(hwnd, tabx, 0, windowW, tabh)) {
TabLayers.draw();
@@ -707,8 +704,6 @@ class UISidebar {
TabFonts.draw();
}
Context.gizmo.visible = UIHeader.inst.worktab.position == SpaceRender;
ui.end();
g.begin(false);
}