Skip to content

Instantly share code, notes, and snippets.

@Greatness7
Created August 28, 2024 04:32
Show Gist options
  • Save Greatness7/f683d80c22ef60342d589992eff0a0d0 to your computer and use it in GitHub Desktop.
Save Greatness7/f683d80c22ef60342d589992eff0a0d0 to your computer and use it in GitHub Desktop.
Export Sphere
--[[
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