File size: 4,414 Bytes
b6a38d7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
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 --east
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()
--this resizes when gizmo hits voxel cell mid
--delta = point((x + halfVoxelSizeX) / voxelSizeX, (y + halfVoxelSizeY) / voxelSizeY, (z + halfVoxelSizeZ) / voxelSizeZ)
--this resizes when gizmo hits voxel cell edge
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 --south
move = point30
end
local oldSize = room.size
local newSize = oldSize + delta
if newSize:x() > 0 and newSize:y() > 0 and newSize:z() >= 0 then --else unhandled behaviour
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 --skip col checks, we already did them
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 |