Begin projection layer
This commit is contained in:
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user