File size: 4,308 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
if config.ModdingToolsInUserMode then return end

local lod_colors = {
	RGB(235,  18,  18),
	RGB( 18, 235,  18),
	RGB( 18,  18, 235),
	RGB(235, 235,  18),
	RGB(235,  18, 235),
	RGB( 18, 235, 235),
}

function MoveToLOD(obj, i)
	if not obj then
		CreateMessageBox(nil, Untranslated("Error"), Untranslated("Please select an object first"))
		return
	end
	if i < 0 or i >= (GetStateLODCount(obj, obj:GetState()) or 5) then
		return
	end
	
	if XLODTestingTool:GetMoveCamera() then
		obj:SetForcedLOD(const.InvalidLODIndex)
	else
		obj:SetForcedLOD(i)
		return
	end
	
	local lod_dist = i == 0 and
		MulDivRound(GetStateLODDistance(obj, obj:GetState(), 1),  80 * obj:GetScale(), 10000) - guim or
		MulDivRound(GetStateLODDistance(obj, obj:GetState(), i), 110 * obj:GetScale(), 10000) + guim
	local pos, lookat = GetCamera()
	local offs = lookat - pos
	pos = obj:GetVisualPos() + SetLen(pos - obj:GetVisualPos(), lod_dist)
	SetCamera(pos, pos + offs)
end

DefineClass.XLODTestingTool = {
	__parents = { "XEditorTool" },
	properties = {
		{ id = "_1", editor = "help", default = false,
			help = function(self) return "<center>" .. (self.obj and self.obj:GetEntity() or "No object selected") end,
		},
		{ id = "_2", editor = "buttons", default = false, buttons = function(self)
				local buttons = {}
				local obj = self.obj
				local lods = obj and GetStateLODCount(obj, obj and obj:GetState()) or 5
				for i = 0, lods - 1 do
					buttons[#buttons + 1] = {
						name = "LOD " .. i,
						func = function() MoveToLOD(obj, i) end,
					}
				end
				return buttons
			end
		},
		{ id = "MoveCamera", name = "Move camera", editor = "bool", default = true, persisted_setting = true, },
	},
	ToolTitle = "LOD Testing",
	Description = {
		"Select an object then use NumPad +/- to zoom in/out and observe LODs change.",
		"(use <style GedHighlight>PageUp</style>/<style GedHighlight>PageDown</style> to change current LOD)\n" ..
		"(use <style GedHighlight>Z</style> to center the object in the view)"
	},
	ActionSortKey = "6",
	ActionIcon = "CommonAssets/UI/Editor/Tools/RoomTools.tga", 
	ToolSection = "Misc",
	UsesCodeRenderables = true,

	obj = false,
	highlighed_obj = false,
	text = false,
}

function XLODTestingTool:Init()
	self:CreateThread("UpdateTextThread", function()
		while true do
			local time = GetPreciseTicks()
			if self.obj then
				local cam_pos = GetCamera()
				local dist = self.obj:GetVisualDist(cam_pos)
				local lod = self.obj:GetCurrentLOD()
				local text = string.format("%dm  LOD %d", dist / guim, lod)
				if self.text.text ~= text then
					self.text:SetText(text)
					self.text:SetColor(lod_colors[lod + 1])
				end
			end
			Sleep(Max(50 - (GetPreciseTicks() - time), 1))
		end
	end)
	self:SetObj(selo())
end

function XLODTestingTool:Done()
	self:SetObj(false)
	self:Highlight(false)
	XEditorSelection = {}
end

function XLODTestingTool:OnMouseButtonDown(pt, button)
	if button == "L" then
		local obj = GetObjectAtCursor()
		if obj then
			self:SetObj(obj)
		end
		return "break"
	end
	return XEditorTool.OnMouseButtonDown(self, pt, button)
end

function XLODTestingTool:SetObj(obj)
	if self.text then
		self.text:delete()
	end
	if obj then
		self.text = Text:new{ hide_in_editor = false }
		local b = obj:GetObjectBBox()
		local max = Max(b:sizex(), b:sizey(), b:sizez())
		self.text:SetPos(obj:GetVisualPos() + point(0, 0, -max / 2))
	end
	self.obj = obj
	CreateRealTimeThread(function()
		XEditorSelection = {obj} -- set as selected without setting const.gofEditorSelection, as we want the Z shortcut to work
		ObjModified(self)
	end)
end

function XLODTestingTool:OnMousePos(pt)
	self:Highlight(GetObjectAtCursor() or false)
end

function XLODTestingTool:Highlight(obj)
	if obj ~= self.highlighted_obj then
		if IsValid(self.highlighted_obj) then
			self.highlighted_obj:ClearHierarchyGameFlags(const.gofEditorHighlight)
		end
		if obj then
			obj:SetHierarchyGameFlags(const.gofEditorHighlight)
		end
		self.highlighted_obj = obj
	end
end

function XLODTestingTool:OnShortcut(shortcut, source, ...)
	if shortcut == "Pageup" then
		MoveToLOD(self.obj, self.obj:GetCurrentLOD() + 1)
		return "break"
	elseif shortcut == "Pagedown" then
		MoveToLOD(self.obj, self.obj:GetCurrentLOD() - 1)
		return "break"
	end
	return XEditorTool.OnShortcut(self, shortcut, source, ...)
end