|
local voxelSizeX = const.SlabSizeX or 0 |
|
local voxelSizeY = const.SlabSizeY or 0 |
|
local voxelSizeZ = const.SlabSizeZ or 0 |
|
local halfVoxelSizeX = voxelSizeX / 2 |
|
local halfVoxelSizeY = voxelSizeY / 2 |
|
local halfVoxelSizeZ = voxelSizeZ / 2 |
|
local InvalidZ = const.InvalidZ |
|
|
|
DefineClass.RoomSizeGizmo = { |
|
__parents = { "XEditorGizmo", "MoveGizmoTool" }, |
|
|
|
HasLocalCSSetting = false, |
|
HasSnapSetting = false, |
|
|
|
Title = "Room size gizmo (Ctrl+\\)", |
|
Description = false, |
|
ActionSortKey = "9", |
|
ActionIcon = "CommonAssets/UI/Editor/Tools/RoomResize.tga", |
|
ActionShortcut = "Ctrl-\\", |
|
UndoOpName = "Resized room(s)", |
|
|
|
r_color = RGB(255, 200, 0), |
|
g_color = RGB(0, 255, 200), |
|
b_color = RGB(200, 0, 255), |
|
|
|
room = false, |
|
sw = false, |
|
} |
|
|
|
local saveMapBlock = false |
|
function OnMsg.PreSaveMap() |
|
saveMapBlock = true |
|
end |
|
|
|
function OnMsg.PostSaveMap() |
|
saveMapBlock = false |
|
end |
|
|
|
function RoomSizeGizmo:CheckStartOperation(pt) |
|
return GetSelectedRoom() and self:IntersectRay(camera.GetEye(), ScreenToGame(pt)) |
|
end |
|
|
|
function RoomSizeGizmo:PosFromSide(r, side) |
|
local b = r.box |
|
if side == "South" then |
|
return b:max() |
|
elseif side == "North" then |
|
return b:min():SetZ(b:max():z()) |
|
elseif side == "West" then |
|
return b:max() - point(b:sizex(), 0, 0) |
|
else |
|
return b:max() - point(0, b:sizey(), 0) |
|
end |
|
end |
|
|
|
function RoomSizeGizmo:Render() |
|
if saveMapBlock then return end |
|
|
|
local obj = not XEditorIsContextMenuOpen() and GetSelectedRoom() |
|
if obj then |
|
self.v_axis_x = axis_x |
|
self.v_axis_y = axis_y |
|
self.v_axis_z = axis_z |
|
self:SetOrientation(axis_z, 0) |
|
|
|
if not self.operation_started then |
|
local sw = obj.selected_wall or "South" |
|
self:SetPos(self:PosFromSide(obj, sw)) |
|
end |
|
|
|
self:ChangeScale() |
|
self:SetMesh(self:RenderGizmo()) |
|
else |
|
self:SetMesh(pstr("")) |
|
end |
|
end |
|
|
|
function RoomSizeGizmo:StartOperation(pt) |
|
if saveMapBlock then return end |
|
|
|
self.initial_positions = {} |
|
self.initial_pos = self:CursorIntersection(pt) |
|
self.initial_gizmo_pos = self:GetVisualPos() |
|
self.room = GetSelectedRoom() |
|
self.sw = self.room.selected_wall or "South" |
|
self.operation_started = true |
|
end |
|
|
|
function RoomSizeGizmo:PerformOperation(pt) |
|
local intersection = self:CursorIntersection(pt) |
|
if intersection then |
|
local vMove = intersection - self.initial_pos |
|
local newPos = self.initial_gizmo_pos + vMove |
|
local room = self.room |
|
local sw = self.sw |
|
self:SetPos(newPos) |
|
local boxEdge = self:PosFromSide(room, sw) |
|
local delta = newPos - boxEdge |
|
local x, y, z = delta:xyz() |
|
|
|
|
|
|
|
delta = point(sign(x) * (abs(x) / voxelSizeX), sign(y) * (abs(y) / voxelSizeY), sign(z) * (abs(z) / voxelSizeZ)) |
|
if delta ~= point30 then |
|
x, y, z = delta:xyz() |
|
local move |
|
if sw == "East" then |
|
move = point(0, y * voxelSizeY, 0) |
|
delta = point(x, y * -1, z) |
|
elseif sw == "West" then |
|
move = point(x * voxelSizeX, 0, 0) |
|
delta = point(x * -1, y, z) |
|
elseif sw == "North" then |
|
move = point(x * voxelSizeX, y * voxelSizeY, 0) |
|
delta = point(x * -1, y * -1, z) |
|
else |
|
move = point30 |
|
end |
|
local oldSize = room.size |
|
local newSize = oldSize + delta |
|
|
|
if newSize:x() > 0 and newSize:y() > 0 and newSize:z() >= 0 then |
|
if VolumeCollisonEnabled and room.enable_collision then |
|
local b = room.box |
|
local mix, miy, miz = b:min():xyz() |
|
local max, may, maz = b:max():xyz() |
|
local mvx, mvy, mvz = move:xyz() |
|
local dx, dy, dz = delta:xyz() |
|
|
|
local testBox = box(mix + mvx, miy + mvy, miz, max + dx * voxelSizeX + mvx, may + dy * voxelSizeY + mvy, maz + dz * voxelSizeZ) |
|
if room:CheckCollision(nil, testBox) then |
|
print("Failed to resize room due to collision with other room!") |
|
return |
|
end |
|
end |
|
|
|
local c = room.enable_collision |
|
room.enable_collision = false |
|
if move ~= point30 then |
|
moveHelperHelper(room, move) |
|
end |
|
room.size = oldSize + delta |
|
SizeSetterHelper(room, oldSize) |
|
room.enable_collision = c |
|
else |
|
print("Room can't shrink below x:1, y:1, z:0 size!") |
|
end |
|
end |
|
end |
|
end |
|
|
|
function RoomSizeGizmo:EndOperation() |
|
MoveGizmo.EndOperation(self) |
|
self.room = false |
|
self.sw = false |
|
end |