|
|
|
|
|
|
|
|
|
|
|
DefineClass.EditorLineGuide = { |
|
__parents = { "Mesh", "CollideLuaObject", "EditorVisibleObject", "EditorCallbackObject" }, |
|
|
|
StandardLength = 10 * guim, |
|
NormalColor = RGB(240, 240, 240), |
|
HighlightColor = RGB(240, 230, 150), |
|
SelectedColor = RGB(240, 230, 40), |
|
|
|
collide_mesh = false, |
|
color = RGB(240, 240, 240), |
|
} |
|
|
|
|
|
local function rotate_to_match(obj, axis1, axis2) |
|
axis1, axis2 = SetLen(axis1, 4096), SetLen(axis2, 4096) |
|
local axis = Cross(axis1, axis2) |
|
if axis ~= point30 then |
|
obj:Rotate(axis, GetAngle(axis1, axis2)) |
|
end |
|
end |
|
|
|
function EditorLineGuide:Set(pos1, pos2, normal) |
|
local pos = (pos1 + pos2) / 2 |
|
self:SetPos(pos) |
|
self:SetOrientation(normal, 0) |
|
self:SetScale(MulDivRound((pos1 - pos2):Len(), 100, self.StandardLength)) |
|
|
|
local axis1 = self:GetRelativePoint(axis_y) - self:GetPos() |
|
local axis2 = pos1 - self:GetPos() |
|
rotate_to_match(self, axis1, axis2) |
|
|
|
self:SetGameFlags(const.gofPermanent) |
|
self:UpdateVisuals() |
|
end |
|
|
|
function EditorLineGuide:GetLength() |
|
return MulDivRound(self.StandardLength, self:GetScale(), 100) |
|
end |
|
|
|
function EditorLineGuide:SetLength(length) |
|
self:SetScale(MulDivRound(length, 100, self.StandardLength)) |
|
self:UpdateVisuals() |
|
end |
|
|
|
function EditorLineGuide:GetPos1() |
|
return self:GetRelativePoint(SetLen(axis_y, self.StandardLength / 2)) |
|
end |
|
|
|
function EditorLineGuide:GetPos2() |
|
return self:GetRelativePoint(-SetLen(axis_y, self.StandardLength / 2)) |
|
end |
|
|
|
function EditorLineGuide:GetNormal() |
|
return self:GetRelativePoint(axis_z) - self:GetVisualPos() |
|
end |
|
|
|
function EditorLineGuide:IsHorizontal() |
|
local tangent = self:GetRelativePoint(axis_y) - self:GetPos() |
|
local angle = GetAngle(tangent, axis_z) / 60 |
|
return abs(angle) > 85 |
|
end |
|
|
|
function EditorLineGuide:IsVertical() |
|
local tangent = self:GetRelativePoint(axis_y) - self:GetPos() |
|
local angle = GetAngle(tangent, axis_z) / 60 |
|
return angle < 5 or angle > 175 |
|
end |
|
|
|
function EditorLineGuide:UpdateVisuals() |
|
if self:GetScale() == 0 then |
|
self:SetMesh(pstr("")) |
|
return |
|
end |
|
|
|
local offset = SetLen(axis_y, self.StandardLength / 2) |
|
local arrowlen = MulDivRound(guim / 2, 100, self:GetScale()) |
|
local normal = SetLen(axis_z, arrowlen) |
|
local along = SetLen(offset, arrowlen / 2) |
|
|
|
local str = pstr("") |
|
str:AppendVertex(offset, self.color) |
|
str:AppendVertex(-offset) |
|
str:AppendVertex(-along) |
|
str:AppendVertex(normal) |
|
str:AppendVertex(normal) |
|
str:AppendVertex(along) |
|
self:SetShader(ProceduralMeshShaders.mesh_linelist) |
|
self:SetMesh(str) |
|
|
|
if IsEditorActive() then |
|
self:SetEnumFlags(const.efVisible) |
|
end |
|
end |
|
|
|
EditorLineGuide.EditorCallbackPlaceCursor = EditorLineGuide.UpdateVisuals |
|
EditorLineGuide.EditorCallbackPlace = EditorLineGuide.UpdateVisuals |
|
EditorLineGuide.EditorCallbackScale = EditorLineGuide.UpdateVisuals |
|
EditorLineGuide.EditorEnter = EditorLineGuide.UpdateVisuals |
|
|
|
function EditorLineGuide:GetBBox() |
|
local grow = guim / 4 |
|
local length = self:GetLength() |
|
return GrowBox(box(0, -length / 2, 0, 0, length / 2, 0), grow, grow, grow) |
|
end |
|
|
|
function EditorLineGuide:TestRay(pos, dir) |
|
|
|
return true |
|
end |
|
|
|
|
|
|
|
|
|
if FirstLoad then |
|
SelectedLineGuides = {} |
|
end |
|
|
|
function EditorLineGuide:SetHighlighted(highlight) |
|
local selected = table.find(SelectedLineGuides, self) |
|
self.color = selected and self.SelectedColor or |
|
highlight and self.HighlightColor or self.NormalColor |
|
self:UpdateVisuals() |
|
end |
|
|
|
function OnMsg.EditorSelectionChanged(objects) |
|
local lines = table.ifilter(objects, function(idx, obj) return IsKindOf(obj, "EditorLineGuide") end ) |
|
if #lines > 0 then |
|
for _, line in ipairs(table.subtraction(lines, SelectedLineGuides)) do |
|
line.color = line.SelectedColor |
|
line:UpdateVisuals() |
|
end |
|
end |
|
if #SelectedLineGuides > 0 then |
|
for _, line in ipairs(table.subtraction(SelectedLineGuides, lines)) do |
|
if IsValid(line) then |
|
line.color = nil |
|
line:UpdateVisuals() |
|
end |
|
end |
|
end |
|
SelectedLineGuides = lines |
|
end |
|
|