Created
August 28, 2024 04:32
-
-
Save Greatness7/f683d80c22ef60342d589992eff0a0d0 to your computer and use it in GitHub Desktop.
Export Sphere
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Export Sphere | |
By Greatness7 | |
Installation: | |
Save as "main.lua" and place the file at "Data Files/mwse/mods/exportSphere/main.lua". | |
Hotkey: Ctrl+Alt+E | |
Press first time to spawn the sphere, use mouse wheel to increase/decrease size, press again to export. | |
--]] | |
local exportHidden = false | |
local exportTypes = { | |
tes3.objectType.activator, | |
tes3.objectType.alchemy, | |
tes3.objectType.ammunition, | |
tes3.objectType.apparatus, | |
tes3.objectType.armor, | |
tes3.objectType.book, | |
tes3.objectType.clothing, | |
tes3.objectType.container, | |
-- tes3.objectType.creature, | |
tes3.objectType.door, | |
tes3.objectType.ingredient, | |
tes3.objectType.light, | |
tes3.objectType.lockpick, | |
tes3.objectType.miscItem, | |
-- tes3.objectType.npc, | |
tes3.objectType.probe, | |
tes3.objectType.repairItem, | |
tes3.objectType.static, | |
tes3.objectType.weapon, | |
} | |
local sphere | |
local function loadSphere() | |
sphere = tes3.loadMesh("mwse\\widgets.nif"):getObjectByName("unitSphere"):clone() | |
sphere.appCulled = true | |
end | |
event.register("initialized", loadSphere) | |
local function showSphere() | |
local vfxRoot = assert(tes3.worldController.vfxManager.worldVFXRoot) | |
vfxRoot:attachChild(sphere, true) | |
sphere.appCulled = false | |
sphere:clearTransforms() | |
sphere:update() | |
sphere:updateProperties() | |
sphere:updateNodeEffects() | |
end | |
local function hideSphere() | |
sphere.parent:detachChild(sphere) | |
sphere.appCulled = true | |
end | |
local function positionSphere() | |
if sphere.appCulled then return end | |
if tes3ui.menuMode() then return end | |
local rayhit = tes3.rayTest{ | |
position = tes3.getPlayerEyePosition(), | |
direction = tes3.getPlayerEyeVector(), | |
ignore = { tes3.player }, | |
} | |
if rayhit then | |
sphere.translation = rayhit.intersection | |
sphere:update() | |
end | |
end | |
event.register("simulate", positionSphere) | |
local function scaleSphere(e) | |
if sphere.appCulled then return end | |
if tes3ui.menuMode() then return end | |
sphere.scale = math.max(0, sphere.scale + e.delta * 0.5) | |
sphere:update() | |
tes3.messageBox("Scale: %.2f", sphere.scale) | |
end | |
event.register("mouseWheel", scaleSphere) | |
local function boundsIntersect(objA, objB) | |
local dist = objA.worldBoundOrigin:distance(objB.worldBoundOrigin) | |
local radi = objA.worldBoundRadius + objB.worldBoundRadius | |
return dist <= radi | |
end | |
local function clean(root) | |
for obj in table.traverse(root.children) do | |
-- remove extra data | |
obj:removeAllExtraData() | |
-- remove dynamic effects | |
if obj:isInstanceOfType(tes3.niType.NiNode) then | |
for i=0, 4 do | |
local effect = obj:getEffect(i) | |
if effect then | |
obj:detachChild(effect) | |
obj:detachEffect(effect) | |
end | |
end | |
end | |
end | |
end | |
local function export() | |
local sphereOrigin = sphere.worldBoundOrigin | |
local sphereRadius = sphere.worldBoundRadius | |
local root = niNode.new() | |
-- collect references | |
for i, cell in pairs(tes3.getActiveCells()) do | |
for ref in cell:iterateReferences(exportTypes) do | |
if ref.sceneNode and not (ref.disabled or ref.deleted) then | |
if boundsIntersect(sphere, ref.sceneNode) then | |
local node = ref.sceneNode:clone() | |
node:removeAllControllers() | |
root:attachChild(node) | |
end | |
end | |
end | |
end | |
-- remove appCulled | |
if not exportHidden then | |
for node in table.traverse(root.children) do | |
if node:isAppCulled() then | |
node.parent:detachChild(node) | |
end | |
end | |
end | |
-- add landscape stuff | |
if not tes3.player.cell.isInterior then | |
local landscapeRoot = tes3.game.worldLandscapeRoot | |
local node = niNode.new() | |
node.name = landscapeRoot.name | |
node.materialProperty = landscapeRoot.materialProperty | |
node.texturingProperty = landscapeRoot.texturingProperty | |
root:attachChild(node) | |
for shape in table.traverse(landscapeRoot.children) do | |
if shape:isInstanceOfType(tes3.niType.NiTriShape) then | |
if boundsIntersect(sphere, shape) then | |
local t = shape.worldTransform.translation:copy() | |
local shape = shape:clone() | |
node:attachChild(shape) | |
shape.translation = t | |
end | |
end | |
end | |
end | |
-- apply scene origin | |
for i, node in pairs(root.children) do | |
if node then | |
node.translation = node.translation - sphereOrigin | |
end | |
end | |
clean(root) | |
lfs.mkdir("data files\\meshes\\g7\\") | |
root:saveBinary("data files\\meshes\\g7\\export.nif") | |
tes3.messageBox("exported to 'meshes\\g7\\export.nif'") | |
end | |
local function onKeyDownE(e) | |
if e.isShiftDown then return end | |
if tes3ui.menuMode() then return end | |
-- Ctrl+Alt+E | |
if e.isControlDown and e.isAltDown then | |
if sphere.appCulled then | |
showSphere() | |
else | |
hideSphere() | |
export() | |
end | |
end | |
end | |
event.register("keyDown", onKeyDownE, { filter = tes3.scanCode.e }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment