Created
December 16, 2022 17:16
-
-
Save Wintrrss1/b5ed74fb8867e65bd4dd1a1c05bd55de to your computer and use it in GitHub Desktop.
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
-- NOTE: Lua version is 5.3 or newer | |
setGlobalEnum("ShaderDrawOrder") | |
setGlobalEnum("ShaderDrawOrderSubOrder") | |
setGlobalEnum("ShaderDrawOrderUserSlot") | |
setGlobalEnum("RenderFormat") | |
-- TextureCompositeEnityData.ddf | |
setGlobalEnum("RuntimeGeneratedTexturesBlendMode") | |
setGlobalEnum("AlphaMode") | |
setGlobalEnum("RecolorMode") | |
setGlobalEnum("RasterizedTextureFormat") | |
-- alternate operation modes | |
mutCaptureMode = false | |
-- brts used by lua must be referenced by launch_sba | |
brts = { | |
armgear = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerArms_brt"), | |
base = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/base_brt"), | |
gear = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerGear_brt"), | |
head = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerHead_brt"), | |
headgear = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerHeadgear_brt"), | |
legs = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerLegs_brt"), | |
presets = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerShaderPresets_brt"), | |
shadow = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerShadow_brt"), | |
uniform = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerUniformTextures_brt"), | |
zonly = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerZOnly_MeshCombine_brt"), | |
vanityItems = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/vanityItems_brt"), | |
vanityGear = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/bundlereftables/playerVanityGear_brt"), | |
} | |
slots = { | |
arms = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerUpperArm_slot"), | |
elbowgearL = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerLeftElbowGear_slot"), | |
elbowgearR = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerRightElbowGear_slot"), | |
hair = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerHair_slot"), | |
strandHair = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerStrandHair_slot"), | |
headaccessory = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerHeadAccessory_slot"), | |
handgearL = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerHandgearL_slot"), | |
handgearR = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerHandgearR_slot"), | |
head = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerHead_slot"), | |
headgear = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerHeadgear_slot"), | |
haircap = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerHairCap_slot"), | |
pants = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerPants_slot"), | |
legs = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerLegs_slot"), | |
shoeL = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerShoeL_slot"), | |
shoeR = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerShoeR_slot"), | |
shadow = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/characterShadow_slot"), | |
torso = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerTorso_slot"), | |
wristgearL = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerLeftWristGear_slot"), | |
wristgearR = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerRightWristGear_slot"), | |
mouthpiece = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/playerMouthpiece_slot"), | |
zonly = lookupDataContainer(ResourceCompartment_Game, "content/common/logic/schematics/slots/PlayerZOnly_slot"), | |
} | |
-- ----------------------------------------------------------------------------------------------------------------------------------------------------------- | |
muscleMaps_ArmNames = { | |
"", | |
"arm_normal", | |
"arm_soft_normal", | |
"arm_ripped_normal", | |
} | |
-- TODO: Enable muscle maps for torso and legs. Currently disabled for M21. | |
muscleMaps_torsoNames = { | |
"", | |
"", | |
"", | |
"", | |
} | |
muscleMaps_legNames = { | |
"", | |
"", | |
"", | |
"", | |
} | |
v_MuscleMaps_torsoNames = { | |
"", | |
"v_Torso_NORM_D", | |
"v_Torso_NORM_H", | |
"v_Torso_NORM_M", | |
} | |
v_MuscleMaps_legNames = { | |
"", | |
"v_Legs_NORM_D", | |
"v_Legs_NORM_H", | |
"v_Legs_NORM_M", | |
} | |
log("FootballRender.LUA Initialized") -- Debug | |
-- =========================================================================================================================================================== | |
-- SCRIPT CONFIG | |
local AllowMissing = true | |
local TestVanityHardcode = false | |
local SETTING_EnableStrandHair = true | |
-- =========================================================================================================================================================== | |
-- SCRIPT CONSTANTS | |
-- many geo's include lods as ports of fbx, no need to specify lods | |
local lod0 = 0 | |
-- most meshes don't contribute to bounding box computations as it will be very expensive | |
-- but at least few have to, otherwise the model will be invisible | |
-- we have lod2 and shadow mesh contributing to bbox | |
local noBoundingBox = false | |
local updateBoundingBox = true | |
local playerDrawOrder = ShaderDrawOrder_OnField | |
local playerDrawOrder_Default = ShaderDrawOrder_Default | |
local playerDrawSubOrder = ShaderDrawOrderSubOrder_Invalid | |
local playerDrawUserSlot_High = ShaderDrawOrderUserSlot_High | |
local playerDrawUserSlot_Medium = ShaderDrawOrderUserSlot_Medium | |
local playerDrawUserSlot_AboveDefaultBelowMedium = ShaderDrawOrderUserSlot_MaddenAboveDefaultBelowMedium | |
local LeftSide = { | |
name = "Left", | |
prefix = "L" | |
} | |
local RightSide = { | |
name = "Right", | |
prefix = "R" | |
} | |
local fallbackhead_name = "meanhead_capture" -- Fallback hack until New Generics are in | |
-- note that directly input shader value may not match up perfectly to values used in photoshop due to pipeline color adjustments | |
local commonColor_Black = {0.015, 0.015, 0.015, 1.0} -- on the 0-255 scale, this is roughly 4 | |
local commonColor_White = {0.92156, 0.92156, 0.92156, 1.0} -- on the 0-255 scale, this is 235 | |
-- =========================================================================================================================================================== | |
-- HELPER FUNCTIONS | |
-- EA_TODO: Add support for a module lua file that contains these helper methods/classes | |
----------------------------------------------------------------------------- | |
local function isLeft(side) | |
return side == LeftSide | |
end | |
----------------------------------------------------------------------------- | |
local function isRight(side) | |
return side == RightSide | |
end | |
----------------------------------------------------------------------------- | |
-- Check to see if array has a value | |
local function has_value (tab, val) | |
for index, value in ipairs(tab) do | |
if value == val then | |
return true | |
end | |
end | |
return false | |
end | |
----------------------------------------------------------------------------- | |
-- Cull String (TA Determined) coming in from CulledRegion list in appearance object | |
local function DrawEnabled(cullString, initData) | |
if initData and initData.Vanity and initData.Vanity.ExtendedVanityData and initData.Vanity.ExtendedVanityData.CulledRegions then | |
return not has_value(initData.Vanity.ExtendedVanityData.CulledRegions, cullString) | |
else | |
return true | |
end | |
end | |
----------------------------------------------------------------------------- | |
local function stripchars(str, chars) | |
local s = str:gsub("["..chars:gsub("%W","%%%1").."]", '') | |
return s | |
end | |
----------------------------------------------------------------------------- | |
local function strStartsWith(inStr, searchStr) | |
return (string.sub(inStr, 1, #searchStr) == searchStr) | |
end | |
local function strEndsWith(inStr, searchStr) | |
return (searchStr == "" or str:sub(-#searchStr) == searchStr) | |
end | |
----------------------------------------------------------------------------- | |
-- Dump a table node to the log (FB Log and tool, see | |
-- https://confluence.ea.com/pages/viewpage.action?spaceKey=madden&title=Football+DB+Messaging+-+aka+Roster+and+Appearance+Tweaker) | |
function log_table(node) | |
local cache, stack, output = {},{},{} | |
local depth = 1 | |
local output_str = "{\n" | |
while true do | |
local size = 0 | |
if node then | |
for k,v in pairs(node) do | |
size = size + 1 | |
end | |
local cur_index = 1 | |
for k,v in pairs(node) do | |
if (cache[node] == nil) or (cur_index >= cache[node]) then | |
if (string.find(output_str,"}",output_str:len())) then | |
output_str = output_str .. ",\n" | |
elseif not (string.find(output_str,"\n",output_str:len())) then | |
output_str = output_str .. "\n" | |
end | |
table.insert(output,output_str) | |
output_str = "" | |
local key | |
if (type(k) == "number" or type(k) == "boolean") then | |
key = "["..tostring(k).."]" | |
else | |
key = "['"..tostring(k).."']" | |
end | |
if (type(v) == "number" or type(v) == "boolean") then | |
output_str = output_str .. string.rep('\t',depth) .. key .. " = "..tostring(v) | |
elseif (type(v) == "table") then | |
output_str = output_str .. string.rep('\t',depth) .. key .. " = {\n" | |
table.insert(stack,node) | |
table.insert(stack,v) | |
cache[node] = cur_index+1 | |
break | |
else | |
output_str = output_str .. string.rep('\t',depth) .. key .. " = '"..tostring(v).."'" | |
end | |
if (cur_index == size) then | |
output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}" | |
else | |
output_str = output_str .. "," | |
end | |
else | |
-- close the table | |
if (cur_index == size) then | |
output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}" | |
end | |
end | |
cur_index = cur_index + 1 | |
end | |
end | |
if (size == 0) then | |
output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}" | |
end | |
if (#stack > 0) then | |
node = stack[#stack] | |
stack[#stack] = nil | |
depth = cache[node] == nil and depth + 1 or depth - 1 | |
else | |
break | |
end | |
end | |
table.insert(output,output_str) | |
output_str = table.concat(output) | |
log(output_str) | |
end | |
----------------------------------------------------------------------------- | |
function tableDeepCopy(obj, seen) | |
if type(obj) ~= 'table' then return obj end | |
if seen and seen[obj] then return seen[obj] end | |
local s = seen or {} | |
local res = setmetatable({}, getmetatable(obj)) | |
s[obj] = res | |
for k, v in pairs(obj) do res[tableDeepCopy(k, s)] = tableDeepCopy(v, s) end | |
return res | |
end | |
----------------------------------------------------------------------------- | |
function setVec(targetField, sourceOverride) | |
fieldCount = 0 | |
for k,v in pairs(targetField) do | |
fieldCount = fieldCount + 1 | |
end | |
if fieldCount == 3 then | |
targetField[1] = sourceOverride.Vec3Value[1] | |
targetField[2] = sourceOverride.Vec3Value[2] | |
targetField[3] = sourceOverride.Vec3Value[3] | |
else | |
targetField[1] = sourceOverride.Vec4Value[1] | |
targetField[2] = sourceOverride.Vec4Value[2] | |
targetField[3] = sourceOverride.Vec4Value[3] | |
targetField[4] = sourceOverride.Vec4Value[4] | |
end | |
end | |
----------------------------------------------------------------------------- | |
local function overrideItem(targetItem, overrides) | |
if targetItem == nil then | |
log("targetItem Nil") | |
--dumpStack() | |
else | |
if overrides ~= nil then | |
count = 0 | |
for k,v in pairs(overrides) do | |
local fieldName = v.FieldName | |
if targetItem[fieldName] ~= nil then | |
--log('Type of field: ' .. fieldName .. ' is ' .. type(targetItem[fieldName])) | |
if type(targetItem[fieldName]) == 'number' then | |
targetItem[fieldName] = v.IntValue | |
elseif type(targetItem[fieldName]) == 'table' then | |
setVec(targetItem[fieldName], v) | |
else | |
targetItem[fieldName] = v.StringValue | |
end | |
else | |
log("Overidden field " .. fieldName .. " does not exist on target item: " .. v.Name) | |
end | |
count = count + 1 | |
end | |
--log("override count " .. count) | |
end | |
end | |
end | |
----------------------------------------------------------------------------- | |
function nonil(var) | |
if var == nil then | |
return "(nil)" | |
else | |
return var | |
end | |
end | |
function vanityLoadComplete(initData) | |
initData.vanityItemData.vanityTrackingEnabled = false | |
log("InitPlayer Futures Complete: " .. initData.vanityItemData.Info) | |
-- clear out the pendingResolves array so that lua can GC the data when finished | |
initData.vanityItemData.pendingResolves = {} | |
initPlayerComplete(initData.vanityItemData.RawInitData, initData) | |
end | |
function startTrackingVanity(initData) | |
initData.vanityItemData.vanityTrackingEnabled = true | |
if initData.vanityItemData.resolvedVanityItems == initData.vanityItemData.requestedVanityItems then | |
vanityLoadComplete(initData) | |
end | |
end | |
----------------------------------------------------------------------------- | |
-- forces True if an empty string or nil is given, otherwise passes through AllowMissing | |
function allowEmptyMissing(assetName) | |
local returnValue = AllowMissing | |
if not assetName or assetName =="" then | |
returnValue = true | |
end | |
return returnValue | |
end | |
----------------------------------------------------------------------------- | |
-- Called before load player, if supplied. initalize any vanity assets, must call initPlayerComplete at some point (within futures) for loadplayer to get called | |
function InitPlayer(incomingInitData, rawInitData) | |
local initData = tableDeepCopy(incomingInitData) | |
initData.vanityItemData = {} | |
local initVanityItemData = initData.vanityItemData | |
local avatarId = 'N/A' | |
if initData.Vanity and initData.Vanity.ExtendedVanityData and initData.Vanity.ExtendedVanityData.AvatarInstanceId and initData.Vanity.ExtendedVanityData.AvatarInstanceId ~= '' then | |
avatarId = initData.Vanity.ExtendedVanityData.AvatarInstanceId | |
end | |
initVanityItemData.Info = initData.JerseyName .. ' (index: ' .. initData.RosterIndex .. ' AVID: ' .. avatarId .. ')' | |
initVanityItemData.RosterIndex = initData.RosterIndex | |
initVanityItemData.RawInitData = rawInitData | |
log("Init Player: " .. initVanityItemData.Info ) | |
initVanityItemData.pendingResolves = {} | |
local pendingResolvesCount = 0 | |
initVanityItemData.vanityTrackingEnabled = false | |
initVanityItemData.requestedVanityItems = 0 -- Must be globally defined | |
initVanityItemData.resolvedVanityItems = 0 -- Must be globally defined | |
if initData.Vanity then | |
local loadout = initData.Vanity.VanityOnFieldLoadout | |
if loadout then | |
loadout = tableDeepCopy(initData.Vanity.VanityOnFieldLoadout) | |
PreloadVanity("UniformHelmet", loadout.UniformHelmetAssetName, "U_Helmet_Starter_B_BLK", loadout.UniformHelmetOverrides, initData) | |
PreloadVanity("UniformJersey", loadout.UniformJerseyAssetName, "U_Jersey_Starter_H_BLK", loadout.UniformJerseyOverrides, initData) | |
PreloadVanity("UniformPants", loadout.UniformPantsAssetName, "U_Pants_None", loadout.UniformPantsOverrides, initData) | |
PreloadVanity("UniformSocks", loadout.UniformSocksAssetName, "U_Socks_Starter_B_BLK", loadout.UniformSocksOverrides, initData) | |
PreloadVanity("HelmetFacemask", loadout.GearFacemaskAssetName, "G_Facemask_HyperShield_2Bar", loadout.GearFacemaskOverrides, initData) | |
PreloadVanity("HelmetVisor", loadout.GearVisorAssetName, "Visor_None", loadout.GearVisorOverrides, initData) | |
PreloadVanity("JerseyStyle", loadout.UniformJerseyStyleAssetName, "JerseyStyle_Tucked", loadout.UniformJerseyStyleOverrides, initData) | |
PreloadVanity("JerseySleeves", loadout.GearJeseySleeveAssetName, "JerseySleeve_Tight", loadout.GearJeseySleeveOverrides, initData) | |
PreloadVanity("Undershirt", loadout.GearUndershirtAssetName, "Body_UpperBody", loadout.GearUndershirtOverrides, initData) | |
PreloadVanity("Backplate", loadout.GearBackplateAssetName, "Backplate_None", loadout.GearBackplateOverrides, initData) | |
PreloadVanity("Flakjacket", loadout.GearFlakjacketAssetName, "Flakjacket_None", loadout.GearFlakjacketOverrides, initData) | |
PreloadVanity("LegsBase", loadout.GearLegsBaseAssetName, "G_CompShorts_Default", loadout.GearLegsBaseOverrides, initData) | |
PreloadVanity("Socks", loadout.GearSockStyleAssetName, "Socks_Layered", loadout.GearSockStyleOverrides, initData) | |
PreloadVanity("LeftSpat", loadout.GearLeftSpatAssetName, "Spats_None", loadout.GearLeftSpatOverrides, initData) | |
PreloadVanity("LeftShoe", loadout.GearLeftShoeAssetName, "U_MaddenSpeedLow_Starter_B_BLK", loadout.GearLeftShoeOverrides, initData) | |
PreloadVanity("LeftCalf", loadout.GearLeftCalfAssetName, "CalfGear_None", loadout.GearLeftCalfOverrides, initData) | |
PreloadVanity("RightSpat", loadout.GearRightSpatAssetName, "Spats_None", loadout.GearRightSpatOverrides, initData) | |
PreloadVanity("RightShoe", loadout.GearRightShoeAssetName, "U_MaddenSpeedLow_Starter_B_BLK", loadout.GearRightShoeOverrides, initData) | |
PreloadVanity("RightCalf", loadout.GearRightCalfAssetName, "CalfGear_None", loadout.GearRightCalfOverrides, initData) | |
PreloadVanity("LeftArmSleeve", loadout.GearLeftArmSleeveAssetName, "ArmSleeve_None", loadout.GearLeftArmSleeveOverrides, initData) | |
PreloadVanity("RightArmSleeve", loadout.GearRightArmSleeveAssetName, "ArmSleeve_None", loadout.GearRightArmSleeveOverrides, initData) | |
PreloadVanity("LeftElbow", loadout.GearLeftElbowAssetName, "ElbowGear_None", loadout.GearLeftElbowOverrides, initData) | |
PreloadVanity("RightElbow", loadout.GearRightElbowAssetName, "ElbowGear_None", loadout.GearRightElbowOverrides, initData) | |
PreloadVanity("LeftWrist", loadout.GearLeftWristAssetName, "WristGear_None", loadout.GearLeftWristOverrides, initData) | |
PreloadVanity("RightWrist", loadout.GearRightWristAssetName, "WristGear_None", loadout.GearRightWristOverrides, initData) | |
PreloadVanity("LeftHand", loadout.GearLeftGloveAssetName, "HandGear_None", loadout.GearLeftGloveOverrides, initData) | |
PreloadVanity("RightHand", loadout.GearRightGloveAssetName, "HandGear_None", loadout.GearRightGloveOverrides, initData) | |
PreloadVanity("Headband", loadout.GearHeadbandAssetName, "Headband_None", loadout.GearHeadbandOverrides, initData) | |
PreloadVanity("Mouthpiece", loadout.GearMouthpieceAssetName, "Mouthpiece_None", loadout.GearMouthpieceOverrides, initData) | |
PreloadVanity("Neckpad", loadout.GearNeckpadAssetName, "Neckpad_None", loadout.GearNeckpadOverrides, initData) | |
PreloadVanity("Towel", loadout.GearTowelAssetName , "Towel_None", loadout.GearTowelOverrides, initData) | |
PreloadVanity("Handwarmer", loadout.GearHandwarmerAssetName, "Handwarmer_None", loadout.GearHandwarmerOverrides, initData) | |
PreloadVanity("HandwarmerMod", loadout.GearHandwarmerModAssetName , "HandwarmerStyle_Front", loadout.GearHandwarmerModOverrides, initData ) | |
PreloadVanity("FaceMarks", loadout.GearFacepaintAssetName, "FaceMarks_None", loadout.GearFacepaintOverrides, initData) | |
pendingResolvesCount = #initData.vanityItemData.pendingResolves -- need to get the count of the resolves as the array might get cleared | |
startTrackingVanity(initData) -- Called to tell futures to use this | |
end | |
else | |
log("NO VANITY") | |
end | |
log("End InitPlayer: " .. initVanityItemData.Info) | |
return pendingResolvesCount | |
end | |
----------------------------------------------------------------------------- | |
function PreloadVanity(fieldName, vanityName, fallbackNames, overrideData, initData) | |
local initVanityItemData = initData.vanityItemData | |
initVanityItemData.requestedVanityItems = initVanityItemData.requestedVanityItems + 1 | |
--log("FIRST CHECK: " .. nonil(fieldName) .. " - " .. nonil(vanityName) .. "." .. fallbackNames) | |
if vanityName == nil or vanityName == '' then | |
vanityName = fallbackNames | |
fallbackNames = '' | |
end | |
local loadAssets = vanityName | |
if fallbackNames ~= nil then | |
loadAssets = loadAssets .. ';' .. fallbackNames | |
end | |
--log("Loading " .. fieldName .. ": " .. nonil(loadAssets) .. "!" .. initVanityItemData.Info ) | |
initVanityItemData.pendingResolves[#initVanityItemData.pendingResolves + 1] = futureCall(function(resultItem) | |
initVanityItemData.resolvedVanityItems = initVanityItemData.resolvedVanityItems + 1 | |
if(resultItem) then | |
local assetData = tableDeepCopy(assetToTable(resultItem)) | |
if overrideData ~= nil and next(overrideData) ~= nil then | |
overrideItem(assetData, overrideData) | |
end | |
initVanityItemData[fieldName] = assetData | |
else | |
log('Note for vanity ' .. fieldName .. 'could not load any of ' .. loadAssets) | |
initVanityItemData[fieldName] = nil | |
end | |
if initVanityItemData.vanityTrackingEnabled and initVanityItemData.resolvedVanityItems == initVanityItemData.requestedVanityItems then | |
vanityLoadComplete(initData) | |
end | |
end, loadAsync(brts.vanityItems, loadAssets, true)) | |
end | |
----------------------------------------------------------------------------- | |
local function loadCommonAssets(initData) | |
local commonAssets = {} | |
local logo_name = string.format("%sLogo01_TRAN;invisible_color", initData.TeamName) | |
commonAssets.logo_texture = loadAsync(brts.gear, logo_name) | |
local degmap_name = string.format("cloth_gear_deg_%s_tile_MASK", initData.DegradationType) | |
commonAssets.degMap = loadAsync(brts.gear, degmap_name) | |
local degmask_name = string.format("cloth_gear_deg_%s_reveal_MASK_array", initData.DegradationType) | |
commonAssets.degMask = loadAsync(brts.gear, degmask_name) | |
return commonAssets | |
end | |
----------------------------------------------------------------------------- | |
local function resolveVanityColors(initData, vanityTablePart) | |
local colorList = nil | |
if vanityTablePart and vanityTablePart.PaletteString then | |
if vanityTablePart.PaletteString == "Custom" then | |
colorList = { | |
primary = tableDeepCopy(vanityTablePart.CustomColor1), | |
secondary = tableDeepCopy(vanityTablePart.CustomColor2), | |
tertiary = tableDeepCopy(vanityTablePart.CustomColor3), | |
quaternary = tableDeepCopy(vanityTablePart.CustomColor4), | |
} | |
--[[ | |
-- this is currently unused since team has no concept in vanity | |
elseif vanityTablePart.PaletteString == "TeamColor" then | |
colorList = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
]]-- | |
elseif vanityTablePart.PaletteString == "White" then | |
colorList = { | |
primary = commonColor_White, | |
secondary = commonColor_White, | |
tertiary = commonColor_White, | |
quaternary = commonColor_White, | |
} | |
elseif vanityTablePart.PaletteString == "Black" then | |
colorList = { | |
primary = commonColor_Black, | |
secondary = commonColor_Black, | |
tertiary = commonColor_Black, | |
quaternary = commonColor_Black, | |
} | |
end | |
else | |
log("Entered vanityColoResolve with no table data or palette string") | |
end | |
return colorList | |
end | |
----------------------------------------------------------------------------- | |
local function convertLeftPartMaskToRight(leftMaskValue) | |
-- This function takes an arm culling mask value and converts it to the right side | |
-- Done by simply bumping the mask 6 slots | |
local rightMaskValue = 0 | |
rightMaskValue = leftMaskValue<<6 | |
return rightMaskValue | |
end | |
----------------------------------------------------------------------------- | |
local function combineCullingMasks(maskList) | |
-- takes a list of maks values and Bitwise ORs them all together | |
combinedMask = 0 | |
for i,regionMaskValue in ipairs(maskList) do | |
combinedMask = combinedMask|regionMaskValue | |
end | |
return combinedMask | |
end | |
----------------------------------------------------------------------------- | |
local function addDegShaderParams(material, initData, degMap, degMask) | |
material:addTexture("deg_pattern_texture", degMap) | |
material:addTexture("deg_maskArrayTexture", degMask) | |
material:addVector("degOffset", initData.JerseyNumberSplit) | |
material:addVector("degColor1", initData.DegradationColor1) | |
material:addVector("degColor2", initData.DegradationColor2) | |
end | |
-- =========================================================================================================================================================== | |
-- LOAD AND BIND FUNCTIONS | |
local function bindArmsNfl(initData, arm_mesh, arm_preset, arm_normal, sleeve_texture, degMap, degMask) | |
local item = createItem("playerUpperArm", slots.arms, initData.laneId, 1) | |
item:addMeshLodPair(lod0, arm_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
local addShaderParams = function(material) | |
-- presets | |
if arm_preset then | |
material:addPreset(arm_preset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- vectors | |
material:addVector("primaryColor", initData.UniformPrimaryColor) | |
material:addVector("secondaryColor", initData.UniformSecondaryColor) | |
material:addVector("regionMaskValue", initData.FullArmRegionMask) | |
material:addVector("armSleeveMaskValue", initData.ArmSleeveMask) | |
material:addVector("leftSleeveColor", initData.LeftArmSleeveColor) | |
material:addVector("rightSleeveColor", initData.RightArmSleeveColor) | |
-- texture | |
if sleeve_texture then | |
material:addTexture("sleeveTexture", sleeve_texture) | |
end | |
if arm_normal then | |
material:addTexture("normalClampTexture", arm_normal) | |
end | |
end | |
item:reserveMaterials(3) | |
addShaderParams(item:addMaterial("arm_lod0_mat")) | |
addShaderParams(item:addMaterial("arm_lod1_mat")) | |
addShaderParams(item:addMaterial("arm_lod2_mat")) | |
return item | |
end | |
local function bindArmsVanity(initData, arm_mesh, arm_preset, sleeveL_mesh, sleeveL_preset, sleeveR_mesh, sleeveR_preset, arm_normal, tapeL_normal, tapeR_normal, degMap, degMask, | |
armsleeveL_colors, armsleeveR_colors) | |
local item = createItem("playerUpperArm", slots.arms, initData.laneId, 3) | |
item:addMeshLodPair(lod0, arm_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
if sleeveL_mesh then | |
item:addMeshLodPair(lod0, sleeveL_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
if sleeveR_mesh then | |
item:addMeshLodPair(lod0, sleeveR_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
local addArmShaderParams = function(material) | |
-- presets | |
material:addPreset(arm_preset) | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- Arm Tape Logic ........................................................................................................... | |
local textureRef = nil | |
local combinedMask = 0 | |
if initData.vanityItemData.LeftArmSleeve.isNormal > 0.5 or initData.vanityItemData.RightArmSleeve.isNormal > 0.5 then | |
if initData.vanityItemData.LeftArmSleeve.isNormal > 0.5 then | |
if tapeL_normal then | |
textureRef = tapeL_normal | |
end | |
combinedMask = initData.vanityItemData.LeftArmSleeve.PartMask | |
end | |
if initData.vanityItemData.RightArmSleeve.isNormal > 0.5 then | |
if not textureRef and tapeR_normal then | |
textureRef = tapeR_normal | |
end | |
-- first shift the mask by 5 (geometry culling for rest of the body uses 6 instead of 5) to get the value of the right side | |
-- mask and then bitwise OR with the left side mask | |
-- ToDO convert literal to constant | |
combinedMask = combinedMask|(initData.vanityItemData.RightArmSleeve.PartMask<<5) | |
end | |
if textureRef then | |
material:addTexture("sleeveTexture", textureRef) | |
end | |
material:addVector("armSleeveMaskValue", combinedMask) | |
if armsleeveL_colors then | |
material:addVector("leftSleeveColor", armsleeveL_colors.primary) | |
end | |
if armsleeveR_colors then | |
material:addVector("rightSleeveColor", armsleeveR_colors.primary) | |
end | |
end | |
--[[ | |
--We don't want to do muscle map based swapping for vanity arms due to different topology | |
if arm_normal then | |
material:addTexture("normalClampTexture", arm_normal) | |
end | |
]]-- | |
-- Arm Culling Logic ..................................................................................................... | |
local maskList = {} | |
--left armsleeve | |
if initData.vanityItemData.LeftArmSleeve.isNormal < 0.1 then | |
maskList[#maskList+1] = initData.vanityItemData.LeftArmSleeve.PartMask | |
end | |
maskList[#maskList+1] = initData.vanityItemData.LeftElbow.PartMask | |
maskList[#maskList+1] = initData.vanityItemData.LeftWrist.PartMask | |
maskList[#maskList+1] = initData.vanityItemData.LeftHand.PartMask | |
--right armsleeve | |
if initData.vanityItemData.RightArmSleeve.isNormal < 0.1 then | |
maskList[#maskList+1] = convertLeftPartMaskToRight(initData.vanityItemData.RightArmSleeve.PartMask) | |
end | |
maskList[#maskList+1] = convertLeftPartMaskToRight(initData.vanityItemData.RightElbow.PartMask) | |
maskList[#maskList+1] = convertLeftPartMaskToRight(initData.vanityItemData.RightWrist.PartMask) | |
maskList[#maskList+1] = convertLeftPartMaskToRight(initData.vanityItemData.RightHand.PartMask) | |
--undershirt | |
maskList[#maskList+1] = initData.vanityItemData.Undershirt.PartMask | |
local fullMask = combineCullingMasks(maskList) | |
material:addVector("regionMaskValue", fullMask) --temporary disable | |
end | |
item:reserveMaterials(9) | |
addArmShaderParams(item:addMaterial("arm_lod0_mat")) | |
addArmShaderParams(item:addMaterial("arm_lod1_mat")) | |
addArmShaderParams(item:addMaterial("arm_lod2_mat")) | |
local addSleeveShaderParams = function(material, tgtPreset, colors) | |
-- presets | |
if tgtPreset then | |
material:addPreset(tgtPreset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
if colors then | |
material:addVector("primaryColor", colors.primary) | |
material:addVector("secondaryColor", colors.secondary) | |
material:addVector("tertiaryColor", colors.tertiary) | |
material:addVector("quaternaryColor", colors.quaternary) | |
end | |
end | |
if initData.vanityItemData.LeftArmSleeve.isNormal < 0.1 then | |
addSleeveShaderParams(item:addMaterial("armSleeveL_lod0_mat"), sleeveL_preset, armsleeveL_colors) | |
addSleeveShaderParams(item:addMaterial("armSleeveL_lod1_mat"), sleeveL_preset, armsleeveL_colors) | |
addSleeveShaderParams(item:addMaterial("armSleeveL_lod2_mat"), sleeveL_preset, armsleeveL_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveL_lod0_mat"), sleeveL_preset, armsleeveL_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveL_lod1_mat"), sleeveL_preset, armsleeveL_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveL_lod2_mat"), sleeveL_preset, armsleeveL_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveL_lod3_mat"), sleeveL_preset, armsleeveL_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveL_lod4_mat"), sleeveL_preset, armsleeveL_colors) | |
end | |
if initData.vanityItemData.RightArmSleeve.isNormal < 0.1 then | |
addSleeveShaderParams(item:addMaterial("armSleeveR_lod0_mat"), sleeveR_preset, armsleeveR_colors) | |
addSleeveShaderParams(item:addMaterial("armSleeveR_lod1_mat"), sleeveR_preset, armsleeveR_colors) | |
addSleeveShaderParams(item:addMaterial("armSleeveR_lod2_mat"), sleeveR_preset, armsleeveR_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveR_lod0_mat"), sleeveR_preset, armsleeveR_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveR_lod1_mat"), sleeveR_preset, armsleeveR_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveR_lod2_mat"), sleeveR_preset, armsleeveR_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveR_lod3_mat"), sleeveR_preset, armsleeveR_colors) | |
addSleeveShaderParams(item:addMaterial("playerArmSleeveR_lod4_mat"), sleeveR_preset, armsleeveR_colors) | |
end | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadArms(items, initData) | |
local chars_to_remove = "'- ." | |
-- Shaquem Griffin Arm Override | |
local arm_name = "arms" | |
if string.lower(initData.UniqueHeadName) == "griffinshaquem_13251" then | |
arm_name = "NoHandL" | |
elseif string.lower(initData.UniqueHeadName) == "hasselljt_20895" then | |
arm_name = "NoHandL_1" | |
end | |
local mesh_name = nil | |
local arm_mesh = nil | |
local preset_name = nil | |
local arm_preset = nil | |
local arm_normal_name = muscleMaps_ArmNames[initData.MuscleType+1] --lua indices start at 1 and not 0 | |
local arm_normal = nil | |
if arm_normal_name == "" then | |
local arms_barycentric = initData.ArmsBarycentric | |
local arms_base = initData.ArmsBase | |
arm_normal_name = muscleMaps_ArmNames[2] | |
if arms_barycentric > 1.5 and arms_barycentric < 2.5 and arms_base > 0.5 then | |
arm_normal_name = muscleMaps_ArmNames[3] | |
elseif arms_barycentric > 0.5 and arms_barycentric < 1.5 and arms_base > 0.5 then | |
arm_normal_name = muscleMaps_ArmNames[4] | |
end | |
end | |
arm_normal = loadAsync(brts.armgear, arm_normal_name, true) | |
local armsleeveL_colors = nil | |
local armsleeveL_colors = nil | |
local armsleeveR_colors = nil | |
local armsleeve_mask = 0 | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout) then | |
armsleeveL_colors = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
armsleeveR_colors = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
preset_name = string.format("%s_ST_preset;player_skin_ST%s_preset;player_skin_ST3_preset", stripchars(initData.UniqueHeadName, chars_to_remove), initData.SkinTone) | |
if mutCaptureMode then | |
preset_name = "player_skin_capture_preset" | |
end | |
arm_preset = loadAsync(brts.presets, preset_name) | |
mesh_name = string.format("%s_metamorph", arm_name) | |
arm_mesh = loadAsync(brts.armgear, mesh_name) | |
local sleeve_name = string.format("%s;%s", | |
initData.RightArmSleeve, | |
initData.LeftArmSleeve) | |
local sleeve_texture = loadAsync(brts.armgear, sleeve_name, AllowMissing) | |
items[#items + 1] = futureCall(bindArmsNfl, initData, arm_mesh, arm_preset, arm_normal, sleeve_texture, | |
initData.commonAssets.degMap, initData.commonAssets.degMask) | |
else | |
-- Vanity | |
-- If IsNormal is true for an ArmSleeve, then we use preset as a texture name on the arm | |
preset_name = string.format("v_%s_ST_preset;vanity_skin_ST%s_preset;vanity_skin_ST3_preset", stripchars(initData.UniqueHeadName, chars_to_remove), initData.SkinTone) | |
arm_preset = loadAsync(brts.vanityGear, preset_name) | |
mesh_name = string.format("%s_metamorph", "v_Arms") | |
arm_mesh = loadAsync(brts.vanityGear, mesh_name) | |
armsleeveL_colors = resolveVanityColors(initData, initData.vanityItemData.LeftArmSleeve) | |
armsleeveR_colors = resolveVanityColors(initData, initData.vanityItemData.RightArmSleeve) | |
local meshL_name = string.format("%s%s_metamorph", initData.vanityItemData.LeftArmSleeve.Model, "L") | |
local presetL_name = string.format("%s%s_preset;%s_preset;%s%s_preset", initData.vanityItemData.LeftArmSleeve.Material, "L", initData.vanityItemData.LeftArmSleeve.Material, initData.vanityItemData.LeftArmSleeve.Model, "L") | |
local tapeL_normal = nil | |
if initData.vanityItemData.LeftArmSleeve.isNormal > 0.5 then | |
tapeL_normal = loadAsync(brts.vanityGear, initData.vanityItemData.LeftArmSleeve.Material, AllowMissing) --this is a normal map in this case | |
end | |
local armsleeveL_mesh = loadAsync(brts.vanityGear, meshL_name, AllowMissing) | |
local armsleeveL_preset = loadAsync(brts.vanityGear, presetL_name, AllowMissing) | |
local meshR_name = string.format("%s%s_metamorph", initData.vanityItemData.RightArmSleeve.Model, "R") | |
local presetR_name = string.format("%s%s_preset;%s_preset;%s%s_preset", initData.vanityItemData.RightArmSleeve.Material, "R", initData.vanityItemData.RightArmSleeve.Material, initData.vanityItemData.RightArmSleeve.Model, "R") | |
local tapeR_normal = nil | |
if initData.vanityItemData.RightArmSleeve.isNormal > 0.5 then | |
tapeR_normal = loadAsync(brts.vanityGear, initData.vanityItemData.RightArmSleeve.Material, AllowMissing) --this is a normal map in this case | |
end | |
local armsleeveR_mesh = loadAsync(brts.vanityGear, meshR_name, AllowMissing) | |
local armsleeveR_preset = loadAsync(brts.vanityGear, presetR_name, AllowMissing) | |
items[#items + 1] = futureCall(bindArmsVanity, initData, arm_mesh, arm_preset, armsleeveL_mesh, armsleeveL_preset, | |
armsleeveR_mesh, armsleeveR_preset, arm_normal, tapeL_normal, tapeR_normal, initData.commonAssets.degMap, initData.commonAssets.degMask, | |
armsleeveL_colors, armsleeveR_colors) | |
end | |
end | |
----------------------------------------------------------------------------- | |
local function bindElbowGear(side, initData, elbowgear, elbowgear_mesh, elbowgear_preset, elbow_colors, degMap, degMask) | |
local item_name = string.format("playerElbowGear%s", side.prefix) | |
local item = createItem(item_name, elbowgear.slot, initData.laneId, 1) | |
if elbowgear_mesh then | |
item:addMeshLodPair(lod0, elbowgear_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
local addShaderParams = function(material) | |
-- presets | |
if elbowgear_preset then | |
material:addPreset(elbowgear_preset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
if elbow_colors then | |
material:addVector("primaryColor", elbow_colors.primary) | |
material:addVector("secondaryColor", elbow_colors.secondary) | |
material:addVector("tertiaryColor", elbow_colors.tertiary) | |
material:addVector("quaternaryColor", elbow_colors.quaternary) | |
end | |
end | |
item:reserveMaterials(3) | |
addShaderParams(item:addMaterial(string.format("playerElbow%s_lod0_mat", side.prefix))) | |
addShaderParams(item:addMaterial(string.format("playerElbow%s_lod1_mat", side.prefix))) | |
addShaderParams(item:addMaterial(string.format("playerElbow%s_lod2_mat", side.prefix))) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadElbowGear(side, items, initData) | |
local elbowgear_mesh = nil | |
local elbowgear_preset = nil | |
local elbowgear = { | |
slot = isLeft(side) and slots.elbowgearL or slots.elbowgearR, | |
model = isLeft(side) and initData.LeftElbowModel or initData.RightElbowModel, | |
material = isLeft(side) and initData.LeftElbowMaterial or initData.RightElbowMaterial, | |
palette = isLeft(side) and initData.LeftElbowPalette or initData.RightElbowPalette, | |
loadoutAsset = nil, | |
loadoutOverrides = nil, | |
} | |
local elbow_colors = nil | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout) then | |
elbow_colors = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
local mesh_name = string.format("%s%s_metamorph", elbowgear.model, side.prefix) | |
local preset_name = string.format("%s%s_%s_preset;%s_preset;player_missing_preset", | |
elbowgear.model, elbowgear.material, elbowgear.palette, | |
elbowgear.model) | |
elbowgear_mesh = loadAsync(brts.armgear, mesh_name, AllowMissing) | |
elbowgear_preset = loadAsync(brts.presets, preset_name) | |
else | |
local elbow_side = isLeft(side) and "LeftElbow" or "RightElbow" | |
elbow_colors = resolveVanityColors(initData, initData.vanityItemData[elbow_side]) | |
local mesh_name = string.format("%s%s_metamorph", initData.vanityItemData[elbow_side].Model, side.prefix) | |
local preset_name = string.format("%s%s_preset;%s%s_preset", initData.vanityItemData[elbow_side].Material, side.prefix, initData.vanityItemData[elbow_side].Model, side.prefix) | |
elbowgear_mesh = loadAsync(brts.vanityGear, mesh_name, AllowMissing) | |
elbowgear_preset = loadAsync(brts.vanityGear, preset_name, AllowMissing) | |
end | |
items[#items + 1] = futureCall(bindElbowGear, side, initData, elbowgear, elbowgear_mesh, elbowgear_preset, elbow_colors, | |
initData.commonAssets.degMap, initData.commonAssets.degMask) | |
end | |
----------------------------------------------------------------------------- | |
local function bindHair(initData, hair_mesh, hair_helmetoff_mesh, hair_collider_mesh, logo_overlay_texture, headgear_color) | |
local item = createItem("playerHair", slots.hair, initData.laneId, 3) | |
item:setIncludeCullTagHashes("Hair") | |
item:setTagHashes("Hair") | |
if hair_mesh then | |
item:addMeshLodPair(lod0, hair_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
if hair_helmetoff_mesh then | |
item:addMeshLodPair(lod0, hair_helmetoff_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
item:addMeshLodPair(lod0, hair_collider_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
return item | |
end | |
-- hair cap item | |
local function bindHaircapItem(initData, haircap_mesh, logo_overlay_texture, headgear_color) | |
local item = createItem("haircap", slots.haircap, initData.laneId) | |
item:setIncludeCullTagHashes("hair_cap") | |
item:setTagHashes("hair_cap") | |
item:addMeshLodPair(lod0, haircap_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
local addShaderParams = function(material) | |
-- Headbands are in the haircap on G4 | |
material:addVector("primaryColor", headgear_color.primary) | |
material:addVector("secondaryColor", headgear_color.secondary) | |
material:addVector("tertiaryColor", headgear_color.tertiary) | |
-- n.b, In at least CharacterTestLevel TeamName is empty... so we load invisible_color here. The defaults in FrostEd are correct, so lets just leave them. | |
-- logo_overlay_texture is loaded by a dynamic string name which uses TeamName. | |
if initData.TeamName and not (initData.TeamName == "") then | |
-- cover potentially two different types of shaders | |
material:addTexture("logoOverlayTexture", logo_overlay_texture) | |
material:addTexture("teamLogo", logo_overlay_texture) | |
end | |
end | |
item:reserveMaterials(1) | |
addShaderParams(item:addMaterial("headband_mat")) | |
return item | |
end | |
-- bind hair accessory item | |
local function bindHairAccessoryItem(initData, hairaccessory_mesh, logo_overlay_texture, headgear_color) | |
local item = createItem("hairaccessory", slots.headaccessory, initData.laneId) | |
item:setIncludeCullTagHashes("hair_accessory") | |
item:setTagHashes("hair_accessory") | |
item:addMeshLodPair(lod0, hairaccessory_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
local addShaderParams = function(material) | |
material:addVector("primaryColor", headgear_color.primary) | |
material:addVector("secondaryColor", headgear_color.secondary) | |
material:addVector("tertiaryColor", headgear_color.tertiary) | |
-- n.b, In at least CharacterTestLevel TeamName is empty... so we load invisible_color here. The defaults in FrostEd are correct, so lets just leave them. | |
-- logo_overlay_texture is loaded by a dynamic string name which uses TeamName. | |
if initData.TeamName and not (initData.TeamName == "") then | |
-- cover potentially two different types of shaders | |
material:addTexture("logoOverlayTexture", logo_overlay_texture) | |
material:addTexture("teamLogo", logo_overlay_texture) | |
end | |
end | |
item:reserveMaterials(1) | |
addShaderParams(item:addMaterial("headband_mat")) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadHair(items, initData) | |
local chars_to_remove = "'- ." | |
local headgear_color = nil | |
headgear_color = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
local haircap_mesh_name = string.format("%s_haircap;gen_%s_haircap;%s;%s_haircap", | |
initData.UniqueHeadName, | |
initData.GenericHeadName, | |
initData.CustomHairCap, | |
fallbackhead_name) | |
local haircap_mesh = loadAsync(brts.head, stripchars(haircap_mesh_name, chars_to_remove), AllowMissing) | |
local hairaccessory_mesh_name = string.format("%s_headaccessory;%s%s_headaccessory;gen_%s_headaccessory", | |
initData.UniqueHeadName, | |
initData.LastName, initData.FirstName, | |
initData.GenericHeadName) | |
local hairaccessory_mesh = loadAsync(brts.head, stripchars(hairaccessory_mesh_name, chars_to_remove), AllowMissing) | |
local hair_mesh_name = string.format("%s_hair;gen_%s_hair;%s;%s_hair", | |
initData.UniqueHeadName, | |
initData.GenericHeadName, | |
initData.CustomHair, | |
fallbackhead_name) | |
local hair_mesh = loadAsync(brts.head, stripchars(hair_mesh_name, chars_to_remove), AllowMissing) | |
--Robby Anderson hair override | |
local hair_helmetoff_mesh_name = string.format("%s_hair_HelmetOff;%s_helmetOff", | |
initData.UniqueHeadName, | |
string.lower(initData.UniqueHeadName) == "andersonrobby_17960" and "None" or initData.HelmetOnHairSimType) | |
local hair_helmetoff_mesh = loadAsync(brts.head, stripchars(hair_helmetoff_mesh_name, chars_to_remove), AllowMissing) | |
local hair_collider_mesh_name = string.format("%s_HairCollider;HairCollider", initData.UniqueHeadName) | |
local hair_collider_mesh = loadAsync(brts.gear, stripchars(hair_collider_mesh_name, chars_to_remove)) | |
items[#items + 1] = futureCall(bindHair, initData, hair_mesh, hair_helmetoff_mesh, hair_collider_mesh, initData.commonAssets.logo_texture, headgear_color) | |
if haircap_mesh then | |
items[#items + 1] = futureCall(bindHaircapItem, initData, haircap_mesh, initData.commonAssets.logo_texture, headgear_color) | |
end | |
if hairaccessory_mesh then | |
items[#items + 1] = futureCall(bindHairAccessoryItem, initData, hairaccessory_mesh, initData.commonAssets.logo_texture, headgear_color) | |
end | |
end | |
----------------------------------------------------------------------------- | |
local function bindStrandHairItem(initData, hair, beard, eye_brow) | |
local item = createItem("strandhair", slots.strandHair, initData.laneId) | |
item:setIncludeCullTagHashes("strand_hair") | |
item:setTagHashes("strand_hair") | |
if hair then item:addMeshLodPair(lod0, hair, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) end | |
if beard then item:addMeshLodPair(lod0, beard, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) end | |
if eye_brow then item:addMeshLodPair(lod0, eye_brow, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) end | |
-- EA_TODO: Add materials here. | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadStrandHair(items, initData) | |
local chars_to_remove = "'- ." | |
-- EA_TODO: Move strand hair to its own BRT to prevent accidental loading of non-strand assets | |
local hair_mesh_name = string.format("%s_strandbind_hair;gen_%s_strandbind_hair;%s_strandbind_hair;%s_strandbind_hair", | |
initData.UniqueHeadName, | |
initData.GenericHeadName, | |
initData.CustomHair, | |
fallbackhead_name) | |
local beard_mesh_name = string.format("%s_strandbind_beard;gen_%s_strandbind_beard;%s_strandbind_hair;%s_strandbind_beard", | |
initData.UniqueHeadName, | |
initData.GenericHeadName, | |
initData.CustomHair, | |
fallbackhead_name) | |
local eyebrow_mesh_name = string.format("%s_strandbind_eyebrow;gen_%s_strandbind_eyebrow;%s_strandbind_hair;%s_strandbind_hair", | |
initData.UniqueHeadName, | |
initData.GenericHeadName, | |
initData.CustomHair, | |
fallbackhead_name ) | |
local allow_missing = true | |
-- EA_TODO: M22 Hack to disable Strand Hair on SSKO players | |
-- SSKO heads contain "C_KO" in the name. Check if this one does so we can disable its strand hair. | |
local isSSKOHead = string.find(initData.UniqueHeadName, "C_KO") ~= nil | |
local shouldLoadStrandHair = (not isSSKOHead) | |
if not isSSKOHead then | |
local hair_mesh = loadAsync(brts.head, stripchars(hair_mesh_name, chars_to_remove), allow_missing) | |
local beard_mesh = loadAsync(brts.head, stripchars(beard_mesh_name, chars_to_remove), allow_missing) | |
local eye_brow_mesh = loadAsync(brts.head, stripchars(eyebrow_mesh_name, chars_to_remove), allow_missing) | |
shouldLoadStrandHair = hair_mesh or beard_mesh or eye_brow_mesh | |
if shouldLoadStrandHair then | |
items[#items + 1] = futureCall(bindStrandHairItem, initData, hair_mesh, beard_mesh, eye_brow_mesh) | |
end | |
end | |
return shouldLoadStrandHair | |
end | |
----------------------------------------------------------------------------- | |
local function bindHead(initData, head_mesh, headacc_mesh, eyepaint_texture, eyepaint_channels) | |
local item = createItem("playerHead", slots.head, initData.laneId, 2) | |
item:addMeshLodPair(lod0, head_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
item:setTagHashes("psd") | |
if headacc_mesh then | |
item:addMeshLodPair(lod0, headacc_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
local addShaderParams = function(material) | |
material:addVector("EBChannels", eyepaint_channels) | |
material:addVector("degOffset", initData.JerseyNumberSplit) | |
material:addTexture("EBTexture", eyepaint_texture) | |
end | |
item:reserveMaterials(3) | |
addShaderParams(item:addMaterial("head_lod0_mat")) | |
addShaderParams(item:addMaterial("head_lod1_mat")) | |
addShaderParams(item:addMaterial("head_lod2_mat")) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadHead(items, initData) | |
local chars_to_remove = "'- ." | |
local head_mesh_name = string.format("%s;gen_%s;%s", | |
initData.UniqueHeadName, | |
initData.GenericHeadName, | |
fallbackhead_name) -- Fallback hack until New Generics are in | |
if initData.CharLogo and initData.CharLogo == "M21_NARRATIVE_HACK" then | |
head_mesh_name = string.format("%s_m21uniHack;%s;gen_%s;%s", | |
initData.UniqueHeadName, | |
initData.UniqueHeadName, | |
initData.GenericHeadName, | |
fallbackhead_name) -- Fallback hack until New Generics are in) | |
end | |
if mutCaptureMode then | |
head_mesh_name = "meanhead_capture" | |
end | |
local head_mesh = loadAsync(brts.head, stripchars(head_mesh_name, chars_to_remove)) | |
local headacc_mesh_name = string.format("%s", initData.FaceAccessory) | |
local headacc_mesh = loadAsync(brts.head, stripchars(headacc_mesh_name, chars_to_remove), AllowMissing) | |
local eyepaint_texture_name = "" | |
local eyepaint_texture = nil | |
local eyepaint_channels = { 0.0, 0.0, 0.0, 0.0 } | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout or not initData.vanityItemData) then | |
eyepaint_texture_name = string.format("%s", initData.EyePaintTexture) | |
eyepaint_texture = loadAsync(brts.head, eyepaint_texture_name) | |
eyepaint_channels = initData.EyePaintChannels | |
if mutCaptureMode then | |
eyepaint_channels = { 0.0, 0.0, 0.0, 0.0 } | |
end | |
else | |
eyepaint_texture_name = string.format("%s", initData.vanityItemData.FaceMarks.Material) | |
if eyepaint_texture_name == "" then | |
eyepaint_texture_name = "eyeBlack" | |
end | |
--eyepaint_texture = loadAsync(brts.vanityGear, eyepaint_texture_name) | |
eyepaint_texture = loadAsync(brts.head, eyepaint_texture_name) --TODO switch this to vanity exclusive texutres once delivered | |
eyepaint_channels = initData.vanityItemData.FaceMarks.FacePaintChannels | |
end | |
items[#items + 1] = futureCall(bindHead, initData, head_mesh, headacc_mesh, eyepaint_texture, eyepaint_channels) | |
end | |
----------------------------------------------------------------------------- | |
local function bindHeadGear(initData, helmetshell_mesh, helmetacc_mesh, helmetfacemask_mesh, helmetvisor_mesh, helmethair_mesh, | |
helmetvisorclip_mesh, helmethaircollider_mesh, helmetshell_preset, helmetacc_preset, helmetfacemask_preset, helmetvisor_preset, greendot_texture, | |
helmAcc_colors, helmFacemask_colors, helmVisor_colors, helmChinstrap_colors) | |
local item = createItem("playerHeadGear", slots.headgear, initData.laneId, 8) | |
item:setIncludeCullTagHashes("Helmet") | |
item:setExcludeCullTagHashes("Hair") | |
item:setExcludeCullTagHashes("hair_cap") | |
item:setTagHashes("Helmet") | |
-- Meshes | |
if helmetshell_mesh then | |
item:addMeshLodPair(lod0, helmetshell_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_AboveDefaultBelowMedium) | |
end | |
if helmetacc_mesh then | |
item:addMeshLodPair(lod0, helmetacc_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_AboveDefaultBelowMedium) | |
end | |
if helmetfacemask_mesh then | |
item:addMeshLodPair(lod0, helmetfacemask_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_AboveDefaultBelowMedium) | |
end | |
if helmetvisor_mesh then | |
item:addMeshLodPair(lod0, helmetvisor_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_AboveDefaultBelowMedium) | |
end | |
if helmethair_mesh then | |
item:addMeshLodPair(lod0, helmethair_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_AboveDefaultBelowMedium) | |
end | |
if helmetvisorclip_mesh then | |
item:addMeshLodPair(lod0, helmetvisorclip_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_AboveDefaultBelowMedium) | |
end | |
if helmethaircollider_mesh then | |
item:addMeshLodPair(lod0, helmethaircollider_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_AboveDefaultBelowMedium) | |
end | |
-- Materials | |
item:reserveMaterials(18) | |
-- HelmetShell | |
local addHelmetShellShaderParams = function(material) | |
if helmetshell_preset then | |
material:addPreset(helmetshell_preset) | |
end | |
material:addVector("helmetBackNumber_selection", initData.JerseyNumberSplit) | |
material:addVector("helmetFrontNumber_selection", initData.JerseyNumberSplit) | |
material:addVector("degAwayTeamColor", initData.OppositeTeamColor) | |
material:addTexture("greendot", greendot_texture) | |
--check for composited uniform | |
if initData.PalletizedUniformData and initData.PalletizedUniformData.IsPalletizedUniform > 0.1 and initData.PalletizedUniformData.PalletizedHelmetColorTextureHandle ~= 0 then | |
--log("Apply Composited Helmet") | |
material:addGenTexture("colorTexture", initData.PalletizedUniformData.PalletizedHelmetColorTextureHandle) | |
end | |
end | |
addHelmetShellShaderParams(item:addMaterial("playerHelmetShell_lod0_mat")) | |
addHelmetShellShaderParams(item:addMaterial("playerHelmetShell_lod1_mat")) | |
addHelmetShellShaderParams(item:addMaterial("playerHelmetShell_lod2_mat")) | |
-- Accessories | |
local addHelmetAccShaderParams = function(material) | |
if helmetacc_preset then | |
material:addPreset(helmetacc_preset) | |
end | |
material:addVector("degOffset", initData.JerseyNumberSplit) | |
if helmAcc_colors then | |
material:addVector("primaryColor", helmAcc_colors.primary) | |
material:addVector("secondaryColor", helmAcc_colors.secondary) | |
material:addVector("tertiaryColor", helmAcc_colors.tertiary) | |
material:addVector("quaternaryColor", helmAcc_colors.quaternary) | |
end | |
end | |
addHelmetAccShaderParams(item:addMaterial("playerHelmetAccessories_lod0_mat")) | |
addHelmetAccShaderParams(item:addMaterial("playerHelmetAccessories_lod1_mat")) | |
addHelmetAccShaderParams(item:addMaterial("playerHelmetAccessories_lod2_mat")) | |
-- Chinstrap - uses the Accessory materials | |
addHelmetAccShaderParams(item:addMaterial("playerHelmetChinstrap_lod0_mat")) | |
addHelmetAccShaderParams(item:addMaterial("playerHelmetChinstrap_lod1_mat")) | |
addHelmetAccShaderParams(item:addMaterial("playerHelmetChinstrap_lod2_mat")) | |
-- Facemask | |
local addHelmetFacemaskShaderParams = function(material) | |
if helmetfacemask_preset then | |
material:addPreset(helmetfacemask_preset) | |
end | |
material:addVector("degOffset", initData.JerseyNumberSplit) | |
if helmFacemask_colors then | |
material:addVector("primaryColor", helmFacemask_colors.primary) | |
material:addVector("secondaryColor", helmFacemask_colors.secondary) | |
material:addVector("tertiaryColor", helmFacemask_colors.tertiary) | |
material:addVector("quaternaryColor", helmFacemask_colors.quaternary) | |
end | |
end | |
addHelmetFacemaskShaderParams(item:addMaterial("playerHelmetFacemask_lod0_mat")) | |
addHelmetFacemaskShaderParams(item:addMaterial("playerHelmetFacemask_lod1_mat")) | |
addHelmetFacemaskShaderParams(item:addMaterial("playerHelmetFacemask_lod2_mat")) | |
-- Visor | |
local addHelmetVisorShaderParams = function(material) | |
if helmetvisor_preset then | |
material:addPreset(helmetvisor_preset) | |
end | |
if helmVisor_colors then | |
if helmVisor_colors.primary then -- we don't always use these for nfl | |
--log("visor palettize main") | |
material:addVector("color1", helmVisor_colors.primary) | |
material:addVector("color2", helmVisor_colors.secondary) | |
material:addVector("color3", helmVisor_colors.tertiary) | |
end | |
if helmVisor_colors.tabPrimary then -- we don't use these for vanity in m21 | |
--log("visor palettize tab") | |
--note the capitalization (first letter capitalized) on the parameters here is different than on the other parts | |
material:addVector("PrimaryColor", helmVisor_colors.tabPrimary) | |
material:addVector("SecondaryColor", helmVisor_colors.tabSecondary) | |
--material:addVector("TertiaryColor", helmVisor_colors.tabTertiary) | |
end | |
end | |
end | |
addHelmetVisorShaderParams(item:addMaterial("playerHelmetVisor_lod0_mat")) | |
addHelmetVisorShaderParams(item:addMaterial("playerHelmetVisor_lod1_mat")) | |
addHelmetVisorShaderParams(item:addMaterial("playerHelmetVisor_lod2_mat")) | |
-- VisorClips | |
local addHelmetVisorClipsShaderParams = function(material) | |
if helmetfacemask_preset then | |
material:addPreset(helmetfacemask_preset) | |
end | |
if helmFacemask_colors then | |
material:addVector("primaryColor", helmFacemask_colors.primary) | |
material:addVector("secondaryColor", helmFacemask_colors.secondary) | |
material:addVector("tertiaryColor", helmFacemask_colors.tertiary) | |
material:addVector("quaternaryColor", helmFacemask_colors.quaternary) | |
end | |
end | |
addHelmetVisorClipsShaderParams(item:addMaterial("playerHelmetVisorClips_lod0_mat")) | |
addHelmetVisorClipsShaderParams(item:addMaterial("playerHelmetVisorClips_lod1_mat")) | |
addHelmetVisorClipsShaderParams(item:addMaterial("playerHelmetVisorClips_lod2_mat")) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
HelmetFacemaskToVisorClip = { | |
-- Facemasks | |
["revokicker"] = "kicker_revo", | |
["revo3barrb"] = "revo3BarRBClip", | |
["revofullcage3"] = "revoFullCage3Clip", | |
["revospeedcage"] = "RevospeedCageClip", | |
["revospeedrobot"] = "revoSpeedrobotClip", | |
["stdbulldog"] = "standardClip", | |
["revospeedkicker"] = nil, | |
["revospeedfullcage2"] = "revospeedCageClip", | |
["g3bn"] = "G3B_revo", | |
["g2b"] = "G3B_revo", | |
["g2bd"] = "G3B_revo", | |
["3barrb"] = "standard2Clip", | |
["3barrbjagged"] = "standard2Clip", | |
["opodw"] = "standard2Clip", | |
["bullrb"] = "standard2Clip", | |
["rkop"] = "standard2Clip", | |
["xenithpredator"] = "XenithPrismClip", | |
["xenithprism"] = "XenithPrismClip", | |
["xenithprowl"] = "XenithProwlClip", | |
["viciskicker"] = "VicisKickerClip", | |
["vengeancefullcagebulldog"] = "VengeanceFullCageBulldogClip", | |
["speedflexcage"] = "speedflexCageClip", | |
["speedflexhalfcage2"] = "speedflexCageClip", | |
["speedflex2barqb"] = "speedflexCageClip", | |
["speedflex2barsingle"] = "speedflexCageClip", | |
["speedflexrobotrbjagged"] = "speedflexCageClip", | |
["speedflex3barsingle"] = "speedflexCageClip", | |
["speedflex3barqb"] = "speedflexCageClip", | |
["speedflex3barrbjagged"] = "speedflexCageClip", | |
["vengeancez102bar"] = "SchuttVengeanceZ10Clip", | |
["vengeancez103barlb"] = "SchuttVengeanceZ10Clip", | |
["vengeancez10cage"] = "SchuttVengeanceZ10Clip", | |
["vengeancez10robot"] = "SchuttVengeanceZ10Clip", | |
["vengeancez10robotrb"] = "SchuttVengeanceZ10Clip", | |
["revospeed2barwr"] = "Revospeed2BarWRClip", | |
["vengeance3barrb"] = "VengeanceClip", | |
["vengeancekicker"] = "VengeanceClip", | |
["vengeanceqb"] = "VengeanceClip", | |
["vengeancerobot"] = "VengeanceClip", | |
["vengeancefullcage"] = "VengeanceClip", | |
["vengeancerobotrb"] = "VengeanceClip", | |
["f72bar"] = "SchuttF7Clip", | |
["f73bar"] = "SchuttF7Clip", | |
["f73barrb"] = "SchuttF7Clip", | |
["f7fullcage"] = "SchuttF7Clip", | |
["f7robotrb"] = "SchuttF7Clip", | |
["f7robot"] = "SchuttF7Clip", | |
-- Helmets | |
["riddell360"] = "riddell360Clip", | |
["speedflex"] = "speedflexClip", | |
["airxp"] = "standardClip", | |
["schutt"] = "standardClip", | |
["standard"] = "standardClip", | |
["revospeed"] = "revoSpeedClip", | |
["revo"] = "revoClip", | |
["xenith"] = "XenithClip", | |
["schuttvengeance"] = "VengeanceClip", | |
["viciszero1"] = "VicisZero1Clip", | |
["xenithepic"] = "XenithClip", | |
["xenithshadow"] = "XenithClip", | |
["v_madden_hypershield"] = "standardClip" | |
} | |
local function getVisorClip(facemaskIn, helmetIn) | |
local visor = HelmetFacemaskToVisorClip[string.lower(facemaskIn)] | |
if not visor then | |
visor = HelmetFacemaskToVisorClip[string.lower(helmetIn)] or "" | |
end | |
return visor | |
end | |
----------------------------------------------------------------------------- | |
local function loadHeadGear(items, initData) | |
local helmetshell_mesh = nil | |
local helmetacc_mesh = nil | |
local helmetfacemask_mesh = nil | |
local helmetvisor_mesh = nil | |
local helmetvisorclip_mesh_name = "" | |
local helmetvisorclip_mesh = nil | |
local helmetshell_preset = nil | |
local helmetacc_preset = nil | |
local helmetfacemask_preset = nil | |
local helmetvisor_preset = nil | |
local helmAcc_colors = nil | |
local helmFacemask_colors = nil | |
local helmVisor_colors = nil | |
local helmChinstrap_colors = nil --needs shader update to fully implement | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout or not initData.vanityItemData) then | |
-- set oakley visor tab colors. We don't do this for vanity since they should be using baked tab textures | |
helmVisor_colors = { | |
tabPrimary = initData.HelmetPrimaryColor, | |
tabSecondary = initData.HelmetSecondaryColor, | |
tabTertiary = initData.HelmetSecondaryColor, --we do not currently use tertiary though the shader supports it | |
} | |
local helmetshell_mesh_name = string.format("helmet_shell_%s", initData.PlayerHelmet) | |
helmetshell_mesh = loadAsync(brts.headgear, helmetshell_mesh_name, AllowMissing) | |
local helmetacc_mesh_name = string.format("helmet_accessories_%s", initData.PlayerHelmet) | |
helmetacc_mesh = loadAsync(brts.headgear, helmetacc_mesh_name, AllowMissing) | |
local helmetfacemask_mesh_name = string.format("helmet_facemask_%s", initData.Facemask) | |
helmetfacemask_mesh = loadAsync(brts.headgear, helmetfacemask_mesh_name, AllowMissing) | |
local visor = initData.Visor == "None" and "None" or "visor" | |
local helmetvisor_mesh_name = string.format("helmet_%s_%s", visor, initData.PlayerHelmet) | |
helmetvisor_mesh = loadAsync(brts.headgear, helmetvisor_mesh_name, AllowMissing) | |
if initData.Visor ~= "None" then | |
helmetvisorclip_mesh_name = string.format("helmet_visorclips_%s", getVisorClip(initData.Facemask, initData.PlayerHelmet)) | |
end | |
helmetvisorclip_mesh = loadAsync(brts.headgear, helmetvisorclip_mesh_name, AllowMissing) | |
local helmetshell_preset_name = string.format("%s_preset;FALLBACK_Helmet_preset", initData.HelmetPreset) | |
-- NARRATIVE HACK | |
if initData.HatType then | |
if initData.HatType == 370 or initData.HatType == 400 or initData.HatType == 410 or initData.HatType == 520 then | |
helmetshell_preset_name = string.format("%s_CFP_preset;FALLBACK_Helmet_preset", initData.HelmetPreset) | |
end | |
end | |
helmetshell_preset = loadAsync(brts.presets, helmetshell_preset_name) | |
local helmetacc_preset_name = string.format("%s_Acc_preset;FALLBACK_Helmet_Acc_preset", initData.HelmetPreset) | |
helmetacc_preset = loadAsync(brts.presets, helmetacc_preset_name) | |
local helmetfacemask_preset_name = string.format("%s_facemask_preset;FALLBACK_Helmet_Facemask_preset", initData.HelmetPreset) | |
helmetfacemask_preset = loadAsync(brts.presets, helmetfacemask_preset_name) | |
local helmetvisor_preset_name = string.format("player_visor_%s_preset;player_visor_preset", initData.Visor) | |
if mutCaptureMode then | |
helmetvisor_preset_name = "player_visor_capture_preset" | |
end | |
helmetvisor_preset = loadAsync(brts.presets, helmetvisor_preset_name) | |
else | |
helmAcc_colors = nil --resolveVanityColors(initData, initData.vanityItemData.UniformHelmet) | |
helmChinstrap_colors = nil --initData.VanityItemData.UniformHelmet.ChinstrapColor | |
-- special visor setup | |
if initData.vanityItemData.HelmetVisor.PaletteString == "Custom" then | |
helmVisor_colors = { | |
primary = tableDeepCopy(initData.vanityItemData.HelmetVisor.CustomColor1), | |
secondary = tableDeepCopy(initData.vanityItemData.HelmetVisor.CustomColor2), | |
tertiary = tableDeepCopy(initData.vanityItemData.HelmetVisor.CustomColor3), | |
quaternary = tableDeepCopy(initData.vanityItemData.HelmetVisor.CustomColor4), | |
} | |
end | |
-- special facemask setup | |
if initData.vanityItemData.UniformHelmet.FacemaskPaletteString == "Custom" then | |
helmFacemask_colors = { | |
primary = tableDeepCopy(initData.vanityItemData.UniformHelmet.FacemaskCustomColor1), | |
secondary = tableDeepCopy(initData.vanityItemData.UniformHelmet.FacemaskCustomColor2), | |
tertiary = tableDeepCopy(initData.vanityItemData.UniformHelmet.FacemaskCustomColor3), | |
quaternary = tableDeepCopy(initData.vanityItemData.UniformHelmet.FacemaskCustomColor4), | |
} | |
elseif initData.vanityItemData.UniformHelmet.FacemaskPaletteString == "TeamColor" then | |
helmFacemask_colors = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
elseif initData.vanityItemData.UniformHelmet.FacemaskPaletteString == "White" then | |
helmFacemask_colors = { | |
primary = commonColor_White, | |
secondary = commonColor_White, | |
tertiary = commonColor_White, | |
quaternary = commonColor_White, | |
} | |
elseif initData.vanityItemData.UniformHelmet.FacemaskPaletteString == "Black" then | |
helmFacemask_colors = { | |
primary = commonColor_Black, | |
secondary = commonColor_Black, | |
tertiary = commonColor_Black, | |
quaternary = commonColor_Black, | |
} | |
end | |
local helmet_item_model = initData.vanityItemData.UniformHelmet.Model | |
local facemask_item_model = initData.vanityItemData.HelmetFacemask.Model | |
local visor_item_model = initData.vanityItemData.HelmetVisor.Model | |
local helmet_item_mat = initData.vanityItemData.UniformHelmet.Material | |
local facemask_item_mat = initData.vanityItemData.UniformHelmet.FacemaskMaterial | |
local visor_item_mat = initData.vanityItemData.HelmetVisor.Material | |
local helmetshell_mesh_name = string.format("%s_shell", helmet_item_model) | |
helmetshell_mesh = loadAsync(brts.vanityGear, helmetshell_mesh_name, AllowMissing) | |
local helmetacc_mesh_name = string.format("%s_accessories", helmet_item_model) | |
helmetacc_mesh = loadAsync(brts.vanityGear, helmetacc_mesh_name, AllowMissing) | |
local helmetfacemask_mesh_name = string.format("helmet_facemask_%s", facemask_item_model) | |
helmetfacemask_mesh = loadAsync(brts.headgear, helmetfacemask_mesh_name, AllowMissing) | |
local helmetvisor_mesh_name = string.format("%s_%s", helmet_item_model, visor_item_model) | |
helmetvisor_mesh = loadAsync(brts.vanityGear, helmetvisor_mesh_name, AllowMissing) | |
if visor_item_model ~= "" then | |
helmetvisorclip_mesh_name = string.format("helmet_visorclips_%s", getVisorClip(facemask_item_model, helmet_item_model)) | |
end | |
local helmetshell_preset_name = string.format("%s_preset_pro;%s_preset;%s;FALLBACK_Helmet_preset", helmet_item_mat, helmet_item_mat, helmet_item_mat) | |
helmetshell_preset = loadAsync(brts.presets, helmetshell_preset_name) | |
local helmetacc_preset_name = string.format("%s_Acc_preset;FALLBACK_Helmet_Acc_preset", helmet_item_mat) | |
helmetacc_preset = loadAsync(brts.presets, helmetacc_preset_name) | |
local helmetfacemask_preset_name = string.format("%s_preset;FALLBACK_Helmet_Facemask_preset", facemask_item_mat) | |
helmetfacemask_preset = loadAsync(brts.presets, helmetfacemask_preset_name, true) | |
local helmetvisor_preset_name = string.format("%s_preset", visor_item_mat) | |
helmetvisorclip_mesh = loadAsync(brts.headgear, helmetvisorclip_mesh_name, true) | |
helmetvisor_preset = loadAsync(brts.vanityGear, helmetvisor_preset_name, true) | |
end | |
local greendot_texture_name = initData.GreenDot == "None" and "invisible_color" or "greenSticker_COL" | |
local greendot_texture = loadAsync(brts.headgear, greendot_texture_name) | |
local helmethair_mesh_name = string.format("%s_hair_helmetOn;%s_helmetOn", | |
initData.UniqueHeadName, | |
initData.HelmetOnHairSimType) | |
local helmethair_mesh = loadAsync(brts.headgear, helmethair_mesh_name, AllowMissing) | |
local helmethaircollider_mesh_name = string.format("%s_HairCollider;HairCollider", initData.UniqueHeadName) | |
local helmethaircollider_mesh = loadAsync(brts.headgear, helmethaircollider_mesh_name, AllowMissing) | |
items[#items + 1] = futureCall(bindHeadGear, initData, helmetshell_mesh, helmetacc_mesh, helmetfacemask_mesh, helmetvisor_mesh, helmethair_mesh, | |
helmetvisorclip_mesh, helmethaircollider_mesh, helmetshell_preset, helmetacc_preset, helmetfacemask_preset, helmetvisor_preset, greendot_texture, | |
helmAcc_colors, helmFacemask_colors, helmVisor_colors, helmChinstrap_colors) | |
end | |
----------------------------------------------------------------------------- | |
local function bindPants(initData, pants_mesh, pants_preset, logo_overlay_texture, degMap, degMask, pants_colors) | |
local item = createItem("playerPants", slots.pants, initData.laneId, 1) | |
-- Meshes | |
if pants_mesh then | |
item:addMeshLodPair(lod0, pants_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_Medium) | |
end | |
-- Materials | |
item:reserveMaterials(3) | |
-- Pants | |
local addPantsShaderParams = function(material) | |
if pants_preset then | |
material:addPreset(pants_preset) | |
end | |
material:addVector("thighNormalArrayTextureSlice", initData.ThighPadNormalSlice) | |
material:addVector("kneeNormalArrayTextureSlice", initData.KneePadNormalSlice) | |
addDegShaderParams(material, initData, degMap, degMask) | |
--check for composited uniform | |
if initData.PalletizedUniformData and initData.PalletizedUniformData.IsPalletizedUniform > 0.1 and initData.PalletizedUniformData.PalletizedPantsColorTextureHandle ~= 0 then | |
--log("Apply Composited Pants") | |
material:addGenTexture("colorTexture", initData.PalletizedUniformData.PalletizedPantsColorTextureHandle) | |
material:addGenTexture("RSMTexture", initData.PalletizedUniformData.PalletizedPantsRSMTextureHandle) | |
material:addGenTexture("normalClampTexture", initData.PalletizedUniformData.PalletizedPantsSeamNormalTextureHandle) | |
end | |
end | |
addPantsShaderParams(item:addMaterial("playerPants_lod0_mat")) | |
addPantsShaderParams(item:addMaterial("playerPants_lod1_mat")) | |
addPantsShaderParams(item:addMaterial("playerPants_lod2_mat")) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadPants(items, initData) | |
local pants_mesh = nil | |
local pants_preset = nil | |
if not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout then | |
local pants_bottom_name = { "pants", "shorts_padless" } | |
local pants_mesh_name = string.format("%s_metamorph", pants_bottom_name[initData.PlayerBottom + 1]) | |
pants_mesh = loadAsync(brts.legs, pants_mesh_name) | |
-- Presets | |
local pants_preset_name = string.format("%s_preset;FALLBACK_Pants_preset", initData.PantsPreset) | |
pants_preset = loadAsync(brts.presets, pants_preset_name) | |
else | |
-- Vanity Items .................................................................................. | |
pants_colors = nil --resolveVanityColors(initData, initData.vanityItemData.UniformPants) | |
local pants_item_model = initData.vanityItemData.UniformPants.Model | |
local pants_item_mat = initData.vanityItemData.UniformPants.Material | |
-- PANTS | |
local pants_mesh_name = string.format("%s_metamorph", pants_item_model) | |
pants_mesh = loadAsync(brts.vanityGear, pants_mesh_name, AllowMissing) | |
local pants_mat_name = "" | |
-- yeah this is a huge hack but it's the reality of the world we live in | |
if pants_item_model == "v_FootballPants_Standard" or pants_item_model == "v_FootballPantsCutoff_AboveKnee" or pants_item_model == "v_FootballPants_AboveKnee" then | |
--log("Pants Uniform Preset") | |
pants_mat_name = string.format("%s_preset_pro;%s_preset;%s", pants_item_mat, pants_item_mat, pants_item_mat) | |
pants_preset = loadAsync(brts.presets, pants_mat_name, AllowMissing) | |
else | |
--log("Pants Gear Preset") | |
pants_mat_name = string.format("s_preset_pro;%s_preset;%s", pants_item_mat, pants_item_mat, pants_item_mat) | |
pants_preset = loadAsync(brts.vanityGear, pants_mat_name, AllowMissing) | |
end | |
end | |
items[#items + 1] = futureCall(bindPants, initData, pants_mesh, pants_preset, initData.commonAssets.logo_texture, | |
initData.commonAssets.degMap, initData.commonAssets.degMask, pants_colors) | |
end | |
----------------------------------------------------------------------------- | |
local function bindLegs(initData, pants_mesh, socks_mesh, towel_mesh, handwarmer_mesh, leftcalf_mesh, rightcalf_mesh, socksunder_mesh, towelcollider_mesh, bottomlegs_mesh, bottomlegs_preset, | |
pants_preset, leftcalf_preset, rightcalf_preset, socks_preset, socks_adjustments, legs_preset, handwarmer_preset, legs_normal, logo_overlay_texture, degMap, degMask, | |
legsbase_mesh, legsbase_preset, pants_colors, legsbase_colors, leftcalf_colors, rightcalf_colors, socksunder_colors, socks_colors, handwarmer_colors) | |
local item = createItem("playerLegs", slots.legs, initData.laneId, 10) | |
if socks_mesh then | |
item:addMeshLodPair(lod0, socks_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_Medium) | |
end | |
if towel_mesh then | |
item:addMeshLodPair(lod0, towel_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_Medium) | |
if towelcollider_mesh then | |
item:addMeshLodPair(lod0, towelcollider_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_Medium) | |
end | |
end | |
if handwarmer_mesh then | |
item:addMeshLodPair(lod0, handwarmer_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_Medium) | |
end | |
if leftcalf_mesh then | |
item:addMeshLodPair(lod0, leftcalf_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_Medium) | |
end | |
if rightcalf_mesh then | |
item:addMeshLodPair(lod0, rightcalf_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_Medium) | |
end | |
if socksunder_mesh then | |
item:addMeshLodPair(lod0, socksunder_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_AboveDefaultBelowMedium) | |
end | |
if bottomlegs_mesh then | |
item:addMeshLodPair(lod0, bottomlegs_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_Medium) | |
end | |
if legsbase_mesh then | |
item:addMeshLodPair(lod0, legsbase_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_Medium) | |
end | |
-- Materials | |
item:reserveMaterials(21) | |
-- Calves | |
local addCalfShaderParams = function(material, input_preset, input_colors) | |
if input_preset then | |
material:addPreset(input_preset) | |
end | |
if input_colors then | |
material:addVector("primaryColor", input_colors.primary) | |
material:addVector("secondaryColor", input_colors.secondary) | |
material:addVector("tertiaryColor", input_colors.tertiary) | |
end | |
addDegShaderParams(material, initData, degMap, degMask) | |
end | |
addCalfShaderParams(item:addMaterial("playerCalfSleeveL_lod0_mat"), leftcalf_preset, leftcalf_colors) | |
addCalfShaderParams(item:addMaterial("playerCalfSleeveL_lod1_mat"), leftcalf_preset, leftcalf_colors) | |
addCalfShaderParams(item:addMaterial("playerCalfSleeveL_lod2_mat"), leftcalf_preset, leftcalf_colors) | |
addCalfShaderParams(item:addMaterial("playerCalfSleeveR_lod0_mat"), rightcalf_preset, rightcalf_colors) | |
addCalfShaderParams(item:addMaterial("playerCalfSleeveR_lod1_mat"), rightcalf_preset, rightcalf_colors) | |
addCalfShaderParams(item:addMaterial("playerCalfSleeveR_lod2_mat"), rightcalf_preset, rightcalf_colors) | |
-- Socks | |
local addSocksShaderParams = function(material) | |
if socks_preset then | |
material:addPreset(socks_preset) | |
end | |
addDegShaderParams(material, initData, degMap, degMask) | |
--apply uv adjustments | |
material:addVector("vOffset", socks_adjustments.offset) | |
material:addVector("vScale", socks_adjustments.scale) | |
--check for composited uniform | |
if initData.PalletizedUniformData and initData.PalletizedUniformData.IsPalletizedUniform > 0.1 and initData.PalletizedUniformData.PalletizedSocksColorTextureHandle ~= 0 then | |
--log("Apply Composited Socks") | |
material:addGenTexture("colorTexture", initData.PalletizedUniformData.PalletizedSocksColorTextureHandle) | |
end | |
end | |
if not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout then | |
addSocksShaderParams(item:addMaterial("playerSocksUnder_lod0_mat")) | |
addSocksShaderParams(item:addMaterial("playerSocksUnder_lod1_mat")) | |
addSocksShaderParams(item:addMaterial("playerSocksUnder_lod2_mat")) | |
else | |
addSocksShaderParams(item:addMaterial("playerSocks_lod0_mat")) | |
addSocksShaderParams(item:addMaterial("playerSocks_lod1_mat")) | |
addSocksShaderParams(item:addMaterial("playerSocks_lod2_mat")) | |
end | |
-- Handwarmer | |
local addHandWarmerShaderParams = function(material) | |
if handwarmer_preset then | |
material:addPreset(handwarmer_preset) | |
end | |
if handwarmer_colors then | |
material:addVector("primaryColor", handwarmer_colors.primary) | |
material:addVector("secondaryColor", handwarmer_colors.secondary) | |
material:addVector("tertiaryColor", handwarmer_colors.tertiary) | |
end | |
material:addTexture("logoOverlayTexture", logo_overlay_texture) | |
addDegShaderParams(material, initData, degMap, degMask) | |
end | |
addHandWarmerShaderParams(item:addMaterial("Handwarmer_lod0_mat")) | |
addHandWarmerShaderParams(item:addMaterial("Handwarmer_lod1_mat")) | |
addHandWarmerShaderParams(item:addMaterial("Handwarmer_lod2_mat")) | |
-- Towel | |
local addTowelShaderParams = function(material) | |
addDegShaderParams(material, initData, degMap, degMask) | |
end | |
addTowelShaderParams(item:addMaterial("towel_lod0_mat")) | |
addTowelShaderParams(item:addMaterial("towel_lod1_mat")) | |
addTowelShaderParams(item:addMaterial("towel_lod2_mat")) | |
-- Socks - uses same shader pararms as Towels | |
addTowelShaderParams(item:addMaterial("playerSocks_lod0_mat")) | |
addTowelShaderParams(item:addMaterial("playerSocks_lod1_mat")) | |
addTowelShaderParams(item:addMaterial("playerSocks_lod2_mat")) | |
local addLegsShaderParams = function(material) | |
material:addPreset(legs_preset) | |
if legs_normal then | |
material:addTexture("normalClampTexture", legs_normal) | |
end | |
end | |
if legs_preset then | |
addLegsShaderParams(item:addMaterial("playerLegs_lod0_mat")) | |
addLegsShaderParams(item:addMaterial("playerLegs_lod1_mat")) | |
addLegsShaderParams(item:addMaterial("playerLegs_lod2_mat")) | |
end | |
-- Vanity: Legs Base | |
local addLegsBaseShaderParams = function(material) | |
if legsbase_preset then | |
material:addPreset(legsbase_preset) | |
end | |
if legsbase_colors then | |
material:addVector("primaryColor", legsbase_colors.primary) | |
material:addVector("secondaryColor", legsbase_colors.secondary) | |
material:addVector("tertiaryColor", legsbase_colors.tertiary) | |
material:addVector("quaternaryColor", legsbase_colors.quaternary) | |
end | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- Culling Logic | |
if initData.vanityItemData then | |
local maskList = {} | |
maskList[#maskList+1] = initData.vanityItemData.UniformPants.PartMask | |
maskList[#maskList+1] = initData.vanityItemData.Socks.PartMask | |
local fullMask = combineCullingMasks(maskList) | |
material:addVector("regionMaskValue", fullMask) | |
end | |
end | |
addLegsBaseShaderParams(item:addMaterial("playerLowerBodyUnder_lod0_mat")) | |
addLegsBaseShaderParams(item:addMaterial("playerLowerBodyUnder_lod1_mat")) | |
addLegsBaseShaderParams(item:addMaterial("playerLowerBodyUnder_lod2_mat")) | |
-- Bare Legs Skintone | |
local addBottomLegsShaderParams = function(material) | |
if bottomlegs_preset then | |
material:addPreset(bottomlegs_preset) | |
end | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- Culling Logic | |
if initData.vanityItemData then | |
local maskList = {} | |
maskList[#maskList+1] = initData.vanityItemData.UniformPants.PartMask | |
maskList[#maskList+1] = initData.vanityItemData.LegsBase.PartMask | |
maskList[#maskList+1] = initData.vanityItemData.Socks.PartMask | |
local fullMask = combineCullingMasks(maskList) | |
material:addVector("regionMaskValue", fullMask) | |
end | |
end | |
if bottomlegs_mesh then | |
addBottomLegsShaderParams(item:addMaterial("legskin_lod0_mat")) | |
addBottomLegsShaderParams(item:addMaterial("legskin_lod1_mat")) | |
addBottomLegsShaderParams(item:addMaterial("legskin_lod2_mat")) | |
end | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadLegs(items, initData) | |
local pants_mesh = nil | |
local leftcalf_mesh = nil | |
local rightcalf_mesh = nil | |
local socksunder_mesh = nil | |
local socks_mesh = nil | |
local handwarmer_mesh = nil | |
local bottomlegs_mesh = nil | |
local bottomlegs_preset = nil | |
local towel_mesh = nil | |
local towelcollider_mesh = nil | |
local pants_preset = nil | |
local leftcalf_preset = nil | |
local rightcalf_preset = nil | |
local socks_preset = nil | |
local handwarmer_preset = nil | |
local legsbase_mesh = nil | |
local legsbase_preset = nil | |
local legsbase_colors = nil | |
local leftcalf_colors = nil | |
local rightcalf_colors = nil | |
local socksunder_colors = nil | |
local socks_colors = nil | |
local handwarmer_colors = nil | |
local legsbase_culling = nil | |
local socks_culling = nil | |
local legs_normal = nil | |
local socks_adjustments = { | |
offset = 0.0, | |
scale = 1.0, | |
} | |
-- TODO: Enable this block of code once leg normal maps exist. This code is currently untested. | |
-- TODO: Refactor indexing into muscleMaps_LegNames based on bitmasking. | |
--[[ | |
local legs_normal_name = muscleMaps_LegNames[initData.MuscleType+1] --lua indices start at 1 and not 0 | |
if legs_normal_name == "" then | |
local legs_barycentric = initData.LegsBarycentric | |
local legs_base = initData.LegsBase | |
legs_normal_name = muscleMaps_LegNames[2] | |
if legs_barycentric > 1.5 and legs_barycentric < 2.5 and legs_base > 0.5 then | |
legs_normal_name = muscleMaps_LegNames[3] | |
elseif legs_barycentric > 0.5 and legs_barycentric < 1.5 and legs_base > 0.5 then | |
legs_normal_name = muscleMaps_LegNames[4] | |
end | |
end | |
legs_normal = loadAsync(brts.legs, legs_normal_name, true) | |
]] | |
if not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout then | |
local pants_bottom_name = { "pants", "shorts_padless" } | |
local legs_bottom_name = { "", "legs" } | |
local socksunder_bottom_name = { "socks_under", "" } | |
handwarmer_colors = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
local pants_mesh_name = string.format("%s_metamorph", pants_bottom_name[initData.PlayerBottom + 1]) | |
pants_mesh = loadAsync(brts.legs, pants_mesh_name) | |
local socksunder_mesh_name = string.format("%s_metamorph", socksunder_bottom_name[initData.PlayerBottom + 1]) | |
socksunder_mesh = loadAsync(brts.legs, socksunder_mesh_name, AllowMissing) | |
local socks_mesh_name = string.format("socks_%s_metamorph", initData.SockHeight) | |
socks_mesh = loadAsync(brts.legs, socks_mesh_name, AllowMissing) | |
-- adjust sock stripes on undersock to oversock height | |
if initData.SockAdjust > 0.5 then | |
if initData.SockHeight == "Low" then | |
socks_adjustments.offset = -0.35 | |
elseif initData.SockHeight == "High" then | |
socks_adjustments.offset = 0.05 | |
socks_adjustments.scale = 2.0 | |
end | |
end | |
local towel_mesh_name = string.format("%s_%s", initData.Towel, initData.ApproxBodyType) | |
if mutCaptureMode then | |
towel_mesh_name = "" | |
end | |
towel_mesh = loadAsync(brts.gear, towel_mesh_name, AllowMissing) | |
towelcollider_mesh = loadAsync(brts.gear, "TowelCollider", AllowMissing) | |
local handwarmer_mesh_name = string.format("%s_metamorph", initData.HandWarmer) | |
handwarmer_mesh = loadAsync(brts.gear, handwarmer_mesh_name, AllowMissing) | |
local bottomlegs_mesh_name = string.format("%s_metamorph", legs_bottom_name[initData.PlayerBottom + 1]) | |
bottomlegs_mesh = loadAsync(brts.armgear, bottomlegs_mesh_name, AllowMissing) -- yeah it's kinda weird that legs are in the armgear brt but it's really because both arms and legs are in "bodies" | |
local bottomlegs_preset_name = string.format("vanity_legskin_ST%s_preset;vanity_legskin_ST3_preset", initData.SkinTone) | |
bottomlegs_preset = loadAsync(brts.presets, bottomlegs_preset_name, AllowMissing) | |
-- Presets | |
local pants_preset_name = string.format("%s_preset;FALLBACK_Pants_preset", initData.PantsPreset) | |
pants_preset = loadAsync(brts.presets, pants_preset_name) | |
local socks_preset_name = string.format("%s_preset;FALLBACK_Socks_preset", initData.SocksPreset) | |
socks_preset = loadAsync(brts.presets, socks_preset_name) | |
else | |
-- Vanity Items .................................................................................. | |
pants_colors = nil --resolveVanityColors(initData, initData.vanityItemData.UniformPants) | |
legsbase_colors = resolveVanityColors(initData, initData.vanityItemData.LegsBase) | |
leftcalf_colors = resolveVanityColors(initData, initData.vanityItemData.LeftCalf) | |
rightcalf_colors = resolveVanityColors(initData, initData.vanityItemData.RightCalf) | |
socks_colors = resolveVanityColors(initData, initData.vanityItemData.UniformSocks) | |
handwarmer_colors = resolveVanityColors(initData, initData.vanityItemData.Handwarmer) | |
local pants_item_model = initData.vanityItemData.UniformPants.Model | |
local legsbase_item_model = initData.vanityItemData.LegsBase.Model | |
local leftcalf_item_model = initData.vanityItemData.LeftCalf.Model | |
local rightcalf_item_model = initData.vanityItemData.RightCalf.Model | |
local socks_item_model = initData.vanityItemData.Socks.Model | |
local handwarmer_item_model = initData.vanityItemData.Handwarmer.Model | |
local pants_item_mat = initData.vanityItemData.UniformPants.Material | |
local legsbase_item_mat = initData.vanityItemData.LegsBase.Material | |
local leftcalf_item_mat = initData.vanityItemData.LeftCalf.Material | |
local rightcalf_item_mat = initData.vanityItemData.RightCalf.Material | |
local socks_item_mat = initData.vanityItemData.UniformSocks.Material | |
local handwarmer_item_mat = initData.vanityItemData.Handwarmer.Model | |
local handwarmer_style = initData.vanityItemData.HandwarmerMod.Model -- not a true model, used to modify handwarmer type | |
local towel_item_model = initData.vanityItemData.Towel.Model | |
local legs_bottom_name = "" | |
legs_normal = nil | |
-- RESOLVE CONFLICTING PARTS | |
-- CompressionPants Full should disable CalfSleeves | |
-- PANTS | |
local pants_mesh_name = string.format("%s_metamorph", pants_item_model) | |
pants_mesh = loadAsync(brts.vanityGear, pants_mesh_name, AllowMissing) | |
local pants_mat_name = "" | |
-- yeah this is a huge hack but it's the reality of the world we live in | |
if pants_item_model == "v_FootballPants_Standard" or pants_item_model == "v_FootballPantsCutoff_AboveKnee" or pants_item_model == "v_FootballPants_AboveKnee" then | |
--log("Pants Uniform Preset") | |
pants_mat_name = string.format("%s_preset_pro;%s_preset;%s", pants_item_mat, pants_item_mat, pants_item_mat) | |
pants_preset = loadAsync(brts.presets, pants_mat_name, AllowMissing) | |
else | |
--log("Pants Gear Preset") | |
pants_mat_name = string.format("s_preset_pro;%s_preset;%s", pants_item_mat, pants_item_mat, pants_item_mat) | |
pants_preset = loadAsync(brts.vanityGear, pants_mat_name, AllowMissing) | |
end | |
-- LEGS BASE | |
local legsbase_mesh_name = string.format("%s_metamorph", legsbase_item_model) | |
legsbase_mesh = loadAsync(brts.vanityGear, legsbase_mesh_name, true) | |
local legsbase_preset_name = string.format("%s_preset", legsbase_item_mat) | |
legsbase_preset = loadAsync(brts.vanityGear, legsbase_preset_name, true) | |
-- CALF SLEEVE/PADS | |
local leftcalf_mesh_name = string.format("%sL_metamorph", leftcalf_item_model) | |
leftcalf_mesh = loadAsync(brts.vanityGear, leftcalf_mesh_name, AllowMissing) | |
local rightcalf_mesh_name = string.format("%sR_metamorph", rightcalf_item_model) | |
rightcalf_mesh = loadAsync(brts.vanityGear, rightcalf_mesh_name, AllowMissing) | |
local leftcalf_preset_name = string.format("%s_preset", leftcalf_item_mat) | |
leftcalf_preset = loadAsync(brts.vanityGear, leftcalf_preset_name, AllowMissing) | |
local rightcalf_preset_name = string.format("%s_preset", rightcalf_item_mat) | |
rightcalf_preset = loadAsync(brts.vanityGear, rightcalf_preset_name, AllowMissing) | |
-- SOCKS | |
local socks_mesh_name = string.format("%s_metamorph", socks_item_model) | |
socks_mesh = loadAsync(brts.vanityGear, socks_mesh_name, AllowMissing) | |
local socks_preset_name = string.format("%s_preset_pro;%s_preset;%s", socks_item_mat, socks_item_mat, socks_item_mat) | |
socks_preset = loadAsync(brts.presets, socks_preset_name, AllowMissing) | |
-- HANDWARMER | |
local handwarmer_mesh_name = string.format("%s_%s_metamorph;%s_metamorph", handwarmer_item_model, handwarmer_style, handwarmer_item_model) | |
handwarmer_mesh = loadAsync(brts.vanityGear, handwarmer_mesh_name, AllowMissing) | |
local handwarmer_preset_name = string.format("%s_preset", handwarmer_item_mat) | |
handwarmer_preset = loadAsync(brts.vanityGear, handwarmer_preset_name, AllowMissing) | |
-- TOWEL | |
local towel_mesh_name = string.format("%s_%s", towel_item_model, initData.ApproxBodyType) -- TODO Temp body type? | |
towel_mesh = loadAsync(brts.vanityGear, towel_mesh_name, AllowMissing) | |
towelcollider_mesh = loadAsync(brts.gear, "TowelCollider", AllowMissing) --TODO does vanity need its own collider mesh? | |
-- BARE LEGS | |
legs_bottom_name = "v_Legs" | |
local bottomlegs_preset_name = "" | |
local legs_normal_name = v_MuscleMaps_legNames[initData.MuscleType+1] | |
legs_normal = loadAsync(brts.vanityGear, legs_normal_name, true) | |
bottomlegs_preset_name = string.format("vanity_legskin_ST%s_preset;vanity_legskin_ST3_preset", initData.SkinTone) | |
local bottomlegs_mesh_name = string.format("%s_metamorph", legs_bottom_name) | |
bottomlegs_mesh = loadAsync(brts.vanityGear, bottomlegs_mesh_name, AllowMissing) | |
bottomlegs_preset_name = string.format("vanity_legskin_ST%s_preset;vanity_legskin_ST3_preset", initData.SkinTone) | |
bottomlegs_preset = loadAsync(brts.vanityGear, bottomlegs_preset_name, AllowMissing) | |
end | |
local legs_preset_name = string.format("%s_legST_preset;player_leg_ST%s_preset;player_leg_ST4_preset", initData.UniqueHeadName, initData.SkinTone) | |
local legs_preset = loadAsync(brts.presets, legs_preset_name) | |
items[#items + 1] = futureCall(bindLegs, initData, pants_mesh, socks_mesh, towel_mesh, handwarmer_mesh, leftcalf_mesh, rightcalf_mesh, socksunder_mesh, towelcollider_mesh, | |
bottomlegs_mesh, bottomlegs_preset, pants_preset, leftcalf_preset, rightcalf_preset, socks_preset, socks_adjustments, legs_preset, handwarmer_preset, legs_normal, | |
initData.commonAssets.logo_texture, initData.commonAssets.degMap, initData.commonAssets.degMask, | |
legsbase_mesh, legsbase_preset, pants_colors, legsbase_colors, leftcalf_colors, rightcalf_colors, socksunder_colors, socks_colors, handwarmer_colors) | |
end | |
----------------------------------------------------------------------------- | |
local function compositeNamePlate(initData, fontAsset) | |
-- Will replace many prefabs/entites in SetupTeam_LP that deal with generating the jersey name. Hardcoding values for testing. | |
local width, height, mips = 3000, 4, 1 | |
local fieldWidth, kerningGap = 1000, 4 | |
local idealScale = 1.81 | |
local texture_id = string.format("playername_%d_%s_%s_%s", initData.UniquePlayerId, initData.FirstName, initData.LastName, getAssetName(fontAsset)) | |
local compositor = createTextureCompositor(texture_id, width, height, mips) | |
compositor:setIndirectText(fontAsset, initData.JerseyName, fieldWidth, kerningGap, initData.JerseyNameMinCoverage, initData.JerseyNameMaxCoverage, initData.JerseyNameScaleAtMin, idealScale) | |
return compositor:generateIndirectText() | |
end | |
----------------------------------------------------------------------------- | |
local function bindTorso(initData, shirt_mesh, backplate_mesh, sleeve_mesh, neckpad_mesh, jersey_preset, jersey_sleeve_preset, probowl_patch_normal, backplate_preset, neckpad_preset, backplate_colors, captain_patch, cpatch_colors, | |
second_patch, jersey_norm, jersey_anim, shoulderpad_preset, namePlateGeneratedMap, degMap, degMask, undershirt_mesh, undershirt_preset, undershirt_colors, torso_normal) | |
-- Questions: Are we binding materials to meshes that have no use for those materials? | |
-- How much is this costing in time/resources? Possible optimization? | |
-- Do all meshes need to update bounding box? | |
-- TODO: move calculation of JerseyIndirectTexturePlacement from Schematics to Lua | |
-- LaneId support | |
local item = createItem("playerTorso", slots.torso, initData.laneId, 5) | |
if shirt_mesh then | |
item:addMeshLodPair(lod0, shirt_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_High) | |
end | |
if sleeve_mesh then | |
item:addMeshLodPair(lod0, sleeve_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_High) | |
end | |
if backplate_mesh then | |
item:addMeshLodPair(lod0, backplate_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_High) | |
end | |
if neckpad_mesh then | |
item:addMeshLodPair(lod0, neckpad_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_High) | |
end | |
if initData.Vanity and initData.Vanity.UseExtendedVanityData and undershirt_mesh then | |
item:addMeshLodPair(lod0, undershirt_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder, playerDrawUserSlot_High) | |
end | |
--item:reserveMaterials(9) | |
----------------------------------------------------------------------------- | |
local addJerseyShaderParams = function(material, initData) | |
local captainsPatchPalettization = (initData.CaptainPatchPrefix == "CaptainsPatch") and {1, 1, 1, 1} or {0, 0, 0, 0} | |
local captainPatchLevelVec = {initData.CaptainPatchLevel, initData.CaptainPatchLevel, initData.CaptainPatchLevel, initData.CaptainPatchLevel} | |
-- presets | |
material:addPreset(jersey_preset) | |
--check for composited uniform | |
-- note Lua converts the bool to a float 0.0 or 1.0 which is why we check for > 0.1 | |
-- need to add check for the handle itself as composited parts can now be mix and matched, this can be negative so we just check for nonzero | |
if initData.PalletizedUniformData and initData.PalletizedUniformData.IsPalletizedUniform > 0.1 and initData.PalletizedUniformData.PalletizedJerseyColorTextureHandle ~= 0 then | |
--log("Apply Composited Jersey") | |
material:addGenTexture("colorTexture", initData.PalletizedUniformData.PalletizedJerseyColorTextureHandle) | |
material:addGenTexture("RSMTexture", initData.PalletizedUniformData.PalletizedJerseyRSMTextureHandle) | |
material:addGenTexture("seamPatternNormTexture", initData.PalletizedUniformData.PalletizedJerseySeamNormalTextureHandle) | |
material:addGenTexture("chestNumbers", initData.PalletizedUniformData.PalletizedChestNumberColorArrayTextureHandle) | |
material:addGenTexture("backNumbers", initData.PalletizedUniformData.PalletizedBackNumberColorArrayTextureHandle) | |
material:addGenTexture("shoulderNumbers", initData.PalletizedUniformData.PalletizedShoulderNumberColorArrayTextureHandle) | |
material:addGenTexture("NameplateFontTexture", initData.PalletizedUniformData.PalletizedNameplateFontColorArrayTextureHandle) | |
material:addGenTexture("sleeveNumbers", initData.PalletizedUniformData.PalletizedSleeveNumberColorArrayTextureHandle) | |
end | |
-- textures | |
material:addTexture("wrinkleNormTexture", jersey_norm) | |
material:addTexture("wrinkleNormTextureAnim", jersey_anim) | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- vectors | |
material:addVector("chestNumber_selection", initData.JerseyNumberSplit) | |
material:addVector("backNumber_selection", initData.JerseyNumberSplit) | |
material:addVector("shoulderNumber_selection", initData.JerseyNumberSplit) | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout or not initData.vanityItemData) then | |
material:addVector("chestNumber_spacing", initData.JerseyNumberSpacing) | |
material:addVector("backNumber_spacing", initData.JerseyNumberSpacing) | |
material:addVector("shoulderNumber_spacing", initData.JerseyNumberSpacing) | |
end | |
if captain_patch then | |
material:addTexture("patchSampler", captain_patch) | |
material:addVector("cPatch_enablePalettization", captainsPatchPalettization) | |
material:addVector("cPatch_starLevel", captainPatchLevelVec) | |
if cpatch_colors then | |
material:addVector("cPatchColor1", cpatch_colors.primary) | |
material:addVector("cPatchColor2", cpatch_colors.secondary) | |
end | |
end | |
if second_patch then | |
material:addTexture("secondPatchSampler", second_patch) | |
end | |
-- swish | |
material:addVector("swishDynamicBlend", {1, 1, 1, 1} ) | |
material:addVector("sleeveNumber_selection", initData.JerseyNumberSplit) | |
if probowl_patch_normal then | |
material:addTexture("ProBowlPatch_Normal", probowl_patch_normal) | |
end | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout or not initData.vanityItemData) then | |
material:addVector("sleeveNumber_spacing", initData.JerseyNumberSpacing) | |
end | |
end | |
addJerseyShaderParams(item:addMaterial("jersey_lod0_mat"), initData) | |
addJerseyShaderParams(item:addMaterial("jersey_lod1_mat"), initData) | |
addJerseyShaderParams(item:addMaterial("jersey_lod2_mat"), initData) | |
addJerseyShaderParams(item:addMaterial("jersey_lod3_mat"), initData) | |
addJerseyShaderParams(item:addMaterial("jersey_lod4_mat"), initData) | |
----------------------------------------------------------------------------- | |
local addSleevesShaderParams = function(material) | |
-- presets | |
if jersey_sleeve_preset then | |
material:addPreset(jersey_sleeve_preset) | |
end | |
--check for composited uniform | |
if initData.PalletizedUniformData and initData.PalletizedUniformData.IsPalletizedUniform > 0.1 and initData.PalletizedUniformData.PalletizedJerseyColorTextureHandle ~= 0 then | |
--log("Apply Composited Sleeves") | |
material:addGenTexture("colorTexture", initData.PalletizedUniformData.PalletizedJerseyColorTextureHandle) | |
material:addGenTexture("RSMTexture", initData.PalletizedUniformData.PalletizedJerseyRSMTextureHandle) | |
material:addGenTexture("seamPatternNormTexture", initData.PalletizedUniformData.PalletizedJerseySeamNormalTextureHandle) | |
material:addGenTexture("sleeveNumbers", initData.PalletizedUniformData.PalletizedSleeveNumberColorArrayTextureHandle) | |
end | |
-- textures | |
material:addTexture("wrinkleNormTexture", jersey_norm) | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- vectors | |
material:addVector("sleeveNumber_selection", initData.JerseyNumberSplit) | |
if probowl_patch_normal then | |
material:addTexture("ProBowlPatch_Normal", probowl_patch_normal) | |
end | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout or not initData.vanityItemData) then | |
material:addVector("sleeveNumber_spacing", initData.JerseyNumberSpacing) | |
end | |
end | |
addSleevesShaderParams(item:addMaterial("playerSleeves_lod0_mat")) | |
addSleevesShaderParams(item:addMaterial("playerSleeves_lod1_mat")) | |
addSleevesShaderParams(item:addMaterial("playerSleeves_lod2_mat")) | |
----------------------------------------------------------------------------- | |
local addBackplateShaderParams = function(material) | |
-- presets | |
if backplate_preset then | |
material:addPreset(backplate_preset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- vectors | |
if backplate_colors then | |
material:addVector("primaryColor", backplate_colors.primary) | |
material:addVector("secondaryColor", backplate_colors.secondary) | |
material:addVector("tertiaryColor", backplate_colors.tertiary) | |
material:addVector("quaternaryColor", backplate_colors.quaternary) | |
end | |
end | |
addBackplateShaderParams(item:addMaterial("playerBackplate_lod0_mat")) | |
addBackplateShaderParams(item:addMaterial("playerBackplate_lod1_mat")) | |
addBackplateShaderParams(item:addMaterial("playerBackplate_lod2_mat")) | |
----------------------------------------------------------------------------- | |
local addNameplateShaderParams = function(material) | |
if namePlateGeneratedMap then | |
material:addGenTexture("NameplateIndirectTexture", namePlateGeneratedMap) | |
material:addGenVector("NameplateIndirectPlacement", namePlateGeneratedMap) | |
else | |
material:addGenTexture("NameplateIndirectTexture", initData.JerseyIndirectTextureHandle) | |
material:addVector("NameplateIndirectPlacement", initData.JerseyIndirectTexturePlacement) | |
end | |
end | |
addNameplateShaderParams(item:addMaterial("jersey_lod0_mat")) | |
addNameplateShaderParams(item:addMaterial("jersey_lod1_mat")) | |
addNameplateShaderParams(item:addMaterial("jersey_lod2_mat")) | |
----------------------------------------------------------------------------- | |
local addUndershirtShaderParams = function(material) | |
-- presets | |
if undershirt_preset then | |
material:addPreset(undershirt_preset) | |
end | |
if undershirt_colors then | |
material:addVector("primaryColor", undershirt_colors.primary) | |
material:addVector("secondaryColor", undershirt_colors.secondary) | |
material:addVector("tertiaryColor", undershirt_colors.tertiary) | |
material:addVector("quaternaryColor", undershirt_colors.quaternary) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- Culling Logic | |
if initData.vanityItemData then | |
local maskList = {} | |
--left armsleeve | |
if initData.vanityItemData.LeftArmSleeve.isNormal < 0.1 then | |
maskList[#maskList+1] = initData.vanityItemData.LeftArmSleeve.PartMask | |
end | |
maskList[#maskList+1] = initData.vanityItemData.LeftElbow.PartMask | |
maskList[#maskList+1] = initData.vanityItemData.LeftWrist.PartMask | |
maskList[#maskList+1] = initData.vanityItemData.LeftHand.PartMask | |
--right armsleeve | |
if initData.vanityItemData.RightArmSleeve.isNormal < 0.1 then | |
maskList[#maskList+1] = convertLeftPartMaskToRight(initData.vanityItemData.RightArmSleeve.PartMask) | |
end | |
maskList[#maskList+1] = convertLeftPartMaskToRight(initData.vanityItemData.RightElbow.PartMask) | |
maskList[#maskList+1] = convertLeftPartMaskToRight(initData.vanityItemData.RightWrist.PartMask) | |
maskList[#maskList+1] = convertLeftPartMaskToRight(initData.vanityItemData.RightHand.PartMask) | |
--jersey | |
maskList[#maskList+1] = initData.vanityItemData.JerseyStyle.PartMask | |
local fullMask = combineCullingMasks(maskList) | |
material:addVector("regionMaskValue", fullMask) --temporary disable | |
end | |
end | |
addUndershirtShaderParams(item:addMaterial("playerUpperBodyUnder_lod0_mat")) | |
addUndershirtShaderParams(item:addMaterial("playerUpperBodyUnder_lod1_mat")) | |
addUndershirtShaderParams(item:addMaterial("playerUpperBodyUnder_lod2_mat")) | |
----------------------------------------------------------------------------- | |
local addTorsoShaderParams = function(material) | |
-- presets | |
if undershirt_preset then | |
material:addPreset(undershirt_preset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
if torso_normal then | |
material:addTexture("normalClampTexture", torso_normal) | |
end | |
-- Culling Logic | |
if initData.vanityItemData then | |
local maskList = {} | |
maskList[#maskList+1] = initData.vanityItemData.JerseyStyle.PartMask | |
maskList[#maskList+1] = initData.vanityItemData.Undershirt.PartMask | |
local fullMask = combineCullingMasks(maskList) | |
material:addVector("regionMaskValue", fullMask) --temporary disable | |
end | |
end | |
addTorsoShaderParams(item:addMaterial("torsoSkin_lod0_mat")) | |
addTorsoShaderParams(item:addMaterial("torsoSkin_lod1_mat")) | |
addTorsoShaderParams(item:addMaterial("torsoSkin_lod2_mat")) | |
----------------------------------------------------------------------------- | |
-- shoulderpads are a seperate material inside rolled_jersey and is not its own mesh | |
local addShoulderpadShaderParams = function(material) | |
-- presets | |
if shoulderpad_preset then | |
material:addPreset(shoulderpad_preset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
end | |
addShoulderpadShaderParams(item:addMaterial("playerShoulderpads_lod0_mat")) | |
addShoulderpadShaderParams(item:addMaterial("playerShoulderpads_lod1_mat")) | |
addShoulderpadShaderParams(item:addMaterial("playerShoulderpads_lod2_mat")) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadTorso(items, generatedTextures, initData) | |
-- Meshes | |
local playerTops = {"jersey", "padlessJersey", "practiceJersey"} | |
local shirt_mesh = nil | |
local sleeve_mesh = nil | |
local jersey_preset_name_data = "" | |
local jersey_preset = nil | |
local jersey_sleeve_preset = nil | |
local shoulderpad_preset = nil | |
local probowl_patch_normal = nil | |
local captain_patch = "" | |
local second_patch = "" | |
local neckpad_mesh = nil | |
local neckpad_preset = nil | |
local undershirt_mesh = nil | |
local undershirt_preset = nil | |
local torso_normal = nil | |
local namePlateGeneratedMap = nil | |
local fontAsset = nil | |
-- seperated backplate only used in vanity with rolled jersey | |
local backplate_mesh = nil | |
local backplate_preset = nil | |
local backplate_colors = nil | |
-- we use captain patch colors through the jersey preset and not at all in vanity | |
local cpatch_colors = nil | |
local undershirt_colors = nil | |
-- TODO: Enable this block of code once torso normal maps exist. This code is currently untested. | |
-- TODO: Refactor indexing into muscleMaps_TorsoNames based on bitmasking. | |
--[[ | |
local torso_normal_name = muscleMaps_TorsoNames[initData.MuscleType+1] --lua indices start at 1 and not 0 | |
if torso_normal_name == "" then | |
local gut_barycentric = initData.GutBarycentric | |
local gut_base = initData.GutBase | |
torso_normal_name = muscleMaps_TorsoNames[2] | |
if gut_barycentric > 1.5 and gut_barycentric < 2.5 and gut_base > 0.5 then | |
torso_normal_name = muscleMaps_TorsoNames[3] | |
elseif gut_barycentric > 0.5 and gut_barycentric < 1.5 and gut_base > 0.5 then | |
torso_normal_name = muscleMaps_TorsoNames[4] | |
end | |
end | |
torso_normal = loadAsync(brts.legs, torso_normal_name, true) | |
]] | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout) then | |
-- Jersey ........................................................................................ | |
-- this fallback setup iss used for gen5 merged jersey sleeves. If the merged model isn't found we fall back to g4. We are making this change universally to prevent needing to diverge this script | |
-- for example, jersey_metamorph + sleeve_long_metamorph in g4 would load as jersey_sleeve_long_metamorph | |
local shirt_mesh_name = string.format("%s_%s_metamorph;%s_metamorph", playerTops[initData.PlayerTop + 1], initData.JerseySleeve, playerTops[initData.PlayerTop + 1]) | |
shirt_mesh = loadAsync(brts.gear, shirt_mesh_name) | |
-- for the same reason as stated above, this is allowed to be missing for g5 | |
local sleeve_mesh_name = string.format("%s_metamorph", initData.JerseySleeve) | |
sleeve_mesh = loadAsync(brts.gear, sleeve_mesh_name, true) | |
-- Presets | |
-- Override for QB Practice jerseys | |
jersey_preset_name_data = (initData.BreathRite == "QB" and initData.PlayerTop == 2) and | |
initData.JerseyPreset .. "_QB" or initData.JerseyPreset | |
local jersey_preset_name = string.format("%s_swish_preset;%s_preset;FALLBACK_jersey_preset", jersey_preset_name_data, jersey_preset_name_data) | |
jersey_preset = loadAsync(brts.presets, jersey_preset_name) | |
local jersey_sleeve_preset_name = string.format("%s_Sleeves_preset;FALLBACK_jersey_Sleeves_preset", jersey_preset_name_data) | |
jersey_sleeve_preset = loadAsync(brts.presets, jersey_sleeve_preset_name) | |
local captain_patch_name = string.format("%s%s%s;invisible_color", initData.CaptainPatchPrefix, initData.CaptainPatchMiddle, initData.CaptainPatchSuffix) | |
captain_patch = loadAsync(brts.gear, captain_patch_name) | |
local second_patch_name = string.format("%s;invisible_color", initData.SecondaryPatch) | |
-- NARRATIVE HACK | |
if initData.HatType then | |
if initData.HatType == 370 or initData.HatType == 400 or initData.HatType == 410 then | |
second_patch_name = "NCAA_Decal_2019_BLACK" | |
elseif initData.HatType == 520 then | |
second_patch_name = "NCAA_Decal_2020_BLACK" | |
end | |
end | |
second_patch = loadAsync(brts.gear, second_patch_name) | |
local neckpad_mesh_name = string.format("%s_%s", initData.Neckpad, initData.ApproxBodyType) | |
neckpad_mesh = loadAsync(brts.gear, neckpad_mesh_name, true) | |
if not (initData.SecondaryPatch == "") then | |
local probowl_patch_normal_name = string.format("%s_normal;invisible_color", initData.SecondaryPatch) | |
probowl_patch_normal = loadAsync(brts.uniform, probowl_patch_normal_name, false) | |
end | |
--nameplate texture | |
if initData.JerseyIndirectTextureHandle == 0 then | |
-- Composite the nameplate | |
local font_name = string.format("%s;EAG_Jersey_2012_GRE_Name_COL", initData.JerseyFontName) | |
fontAsset = loadAsync(brts.uniform, font_name) | |
namePlateGeneratedMap = futureCall(compositeNamePlate, initData, fontAsset) | |
generatedTextures[#generatedTextures + 1] = namePlateGeneratedMap | |
end | |
else | |
-- Vanity Items .................................................................................. | |
local shirt_item_model = initData.vanityItemData.JerseyStyle.Model | |
local shirt_item_mat = initData.vanityItemData.UniformJersey.Material | |
local sleeve_item_model = initData.vanityItemData.JerseySleeves.Model | |
local undershirt_item_model = initData.vanityItemData.Undershirt.Model | |
local undershirt_item_mat = initData.vanityItemData.Undershirt.Material | |
local shoulderpad_item_mat = "" --initData.vanityItemData.UniformJersey.Material | |
local neckpad_item_model = initData.vanityItemData.Neckpad.Model | |
local neckpad_item_mat = initData.vanityItemData.Neckpad.Material | |
undershirt_colors = resolveVanityColors(initData, initData.vanityItemData.Undershirt) | |
-- Jersey ........................................................................................ | |
local shirt_mesh_name = string.format("%s_metamorph", shirt_item_model) | |
shirt_mesh = loadAsync(brts.vanityGear, shirt_mesh_name) | |
local sleeve_mesh_name = string.format("%s_metamorph", sleeve_item_model) | |
sleeve_mesh = loadAsync(brts.vanityGear, sleeve_mesh_name, true) | |
-- Presets | |
local jersey_preset_name = string.format("%s_preset_pro;%s_preset;%s;FALLBACK_jersey_preset", shirt_item_mat, shirt_item_mat, shirt_item_mat) | |
jersey_preset = loadAsync(brts.vanityGear, jersey_preset_name) | |
local jersey_sleeve_preset_name = string.format("%s_Sleeves_preset_pro;%s_Sleeves_preset;FALLBACK_jersey_Sleeves_preset", shirt_item_mat, shirt_item_mat) | |
jersey_sleeve_preset = loadAsync(brts.vanityGear, jersey_sleeve_preset_name) | |
local captain_patch_name = "" --string.format("%s%s%s;invisible_color", initData.CaptainPatchPrefix, initData.CaptainPatchMiddle, initData.CaptainPatchSuffix) | |
captain_patch = loadAsync(brts.vanityGear, captain_patch_name, true) | |
local second_patch_name = "" --string.format("%s;invisible_color", initData.SecondaryPatch) | |
second_patch = loadAsync(brts.vanityGear, second_patch_name, true) | |
local shoulderpad_preset_name = string.format("%s_preset;v_Jersey_Rolled_jerseyGear_preset", shoulderpad_item_mat) | |
shoulderpad_preset = loadAsync(brts.vanityGear, shoulderpad_preset_name, true) | |
-- Undershirt / Upper Base Layer ..................................................................... | |
local undershirt_preset_name = string.format("%s_preset;FALLBACK_jersey_preset", undershirt_item_mat) | |
if undershirt_item_model == "v_Torso" then | |
-- this shouldn't be necessary and i cannot actually repro the issue in the bug but there are some bugs | |
-- claiming belly clipping still occuring, so disabling torso with certain jersey styles | |
if shirt_item_model == "v_Jersey_Tucked" or shirt_item_model == "v_Jersey_Untucked" then | |
undershirt_item_model = "None" | |
end | |
local torso_normal_name = v_MuscleMaps_torsoNames[initData.MuscleType+1] | |
torso_normal = loadAsync(brts.vanityGear, torso_normal_name, true) | |
undershirt_preset_name = string.format("vanity_torsoskin_ST%s_preset;vanity_torsoskin_ST3_preset", initData.SkinTone) | |
end | |
local undershirt_mesh_name = string.format("%s_metamorph", undershirt_item_model) | |
log(undershirt_mesh_name) | |
undershirt_mesh = loadAsync(brts.vanityGear, undershirt_mesh_name, true) | |
undershirt_preset = loadAsync(brts.vanityGear, undershirt_preset_name, true) | |
local neckpad_mesh_name = string.format("%s_%s", neckpad_item_model, initData.ApproxBodyType) | |
neckpad_mesh = loadAsync(brts.vanityGear, neckpad_mesh_name, true) | |
local backplate_mesh_name = "" | |
local backplate_preset_name = "" | |
-- Exposed Backplate ................................................................................. | |
-- TODO add field to jersey style for exposed backplate so we don't have to match based on model name | |
if shirt_item_model == "v_Jersey_Rolled" and initData.vanityItemData.Backplate and initData.vanityItemData.Backplate.Model ~= "" then | |
backplate_colors = resolveVanityColors(initData, initData.vanityItemData.Backplate) | |
backplate_mesh_name = string.format("%s_metamorph", initData.vanityItemData.Backplate.Model) | |
backplate_mesh = loadAsync(brts.vanityGear, backplate_mesh_name, true) | |
backplate_preset_name = string.format("%s_preset", initData.vanityItemData.Backplate.Material) | |
backplate_preset = loadAsync(brts.vanityGear, backplate_preset_name, true) | |
end | |
--nameplate texture | |
if initData.JerseyIndirectTextureHandle == 0 then | |
-- Composite the nameplate | |
local font_name = string.format("%s;EAG_Jersey_2012_GRE_Name_COL", initData.vanityItemData.UniformJersey.NameplateTexture) | |
fontAsset = loadAsync(brts.uniform, font_name) | |
namePlateGeneratedMap = futureCall(compositeNamePlate, initData, fontAsset) | |
generatedTextures[#generatedTextures + 1] = namePlateGeneratedMap | |
end | |
end | |
-- Common Textures ............................................................................... | |
local jerseyWrinkleTypes = {"JerseyWrinkles", "PadlessJersey_Wrinkles", "JerseyWrinkles"} | |
local jerseyWrinkleType = jerseyWrinkleTypes[initData.PlayerTop + 1] | |
local jersey_norm_name = string.format("%s_%s;%s_%s;%s_%s;%s_D", | |
jerseyWrinkleType, initData.FlakJacket, | |
jerseyWrinkleType, initData.Backplate, | |
jerseyWrinkleType, initData.ApproxBodyType, | |
jerseyWrinkleType) | |
local jersey_norm = loadAsync(brts.gear, jersey_norm_name) | |
local jersey_anim_name = string.format("%s_%s_anim;%s_%s_anim;%s_%s_anim;%s_D_anim", | |
jerseyWrinkleType, initData.FlakJacket, | |
jerseyWrinkleType, initData.Backplate, | |
jerseyWrinkleType, initData.ApproxBodyType, | |
jerseyWrinkleType) | |
local jersey_anim = loadAsync(brts.gear, jersey_anim_name) | |
items[#items + 1] = futureCall(bindTorso, initData, shirt_mesh, backplate_mesh, sleeve_mesh, neckpad_mesh, jersey_preset, jersey_sleeve_preset, probowl_patch_normal, | |
backplate_preset, neckpad_preset, backplate_colors, captain_patch, cpatch_colors, second_patch, jersey_norm, jersey_anim, | |
shoulderpad_preset, namePlateGeneratedMap, initData.commonAssets.degMap, initData.commonAssets.degMask, undershirt_mesh, undershirt_preset, | |
undershirt_colors, torso_normal) | |
end | |
----------------------------------------------------------------------------- | |
local function bindHandGear(side, initData, handgear, handgear_mesh, handgear_preset, hand_colors, degMap, degMask) | |
local item_name = string.format("playerHandGear%s", side.prefix) | |
local item = createItem(item_name, handgear.slot, initData.laneId, 1) | |
if handgear_mesh then | |
item:addMeshLodPair(lod0, handgear_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
local addShaderParams = function(material) | |
-- presets | |
if handgear_preset then | |
material:addPreset(handgear_preset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- vectors | |
if hand_colors then | |
material:addVector("primaryColor", hand_colors.primary) | |
material:addVector("secondaryColor", hand_colors.secondary) | |
material:addVector("tertiaryColor", hand_colors.tertiary) | |
material:addVector("quaternaryColor", hand_colors.quaternary) | |
end | |
end | |
item:reserveMaterials(3) | |
addShaderParams(item:addMaterial(string.format("playerGlove%s_lod0_mat", side.prefix))) | |
addShaderParams(item:addMaterial(string.format("playerGlove%s_lod1_mat", side.prefix))) | |
addShaderParams(item:addMaterial(string.format("playerGlove%s_lod2_mat", side.prefix))) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadHandGear(side, items, initData) | |
local handgear_mesh = nil | |
local handgear_preset = nil | |
local handgear = { | |
slot = isLeft(side) and slots.handgearL or slots.handgearR, | |
model = isLeft(side) and initData.LeftHandModel or initData.RightHandModel, | |
material = isLeft(side) and initData.LeftHandMaterial or initData.RightHandMaterial, | |
palette = isLeft(side) and initData.LeftHandPalette or initData.RightHandPalette, | |
loadoutAsset = nil, | |
loadoutOverrides = nil, | |
} | |
local hand_colors = nil | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout) then | |
hand_colors = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
local mesh_name = string.format("%s%s_metamorph", handgear.model, side.prefix) | |
local preset_name = string.format("%s%s_%s_preset;%s%s_preset;%s_preset;player_missing_preset", | |
handgear.model, handgear.material, handgear.palette, | |
handgear.model, handgear.material, | |
handgear.model) | |
handgear_mesh = loadAsync(brts.armgear, mesh_name, AllowMissing) | |
handgear_preset = loadAsync(brts.presets, preset_name) | |
else | |
local hand_side = isLeft(side) and "LeftHand" or "RightHand" | |
hand_colors = resolveVanityColors(initData, initData.vanityItemData[hand_side]) | |
local mesh_name = string.format("%s%s_metamorph", initData.vanityItemData[hand_side].Model, side.prefix) | |
local preset_name = string.format("%s_preset;%s_preset", initData.vanityItemData[hand_side].Material, initData.vanityItemData[hand_side].Model) | |
handgear_mesh = loadAsync(brts.vanityGear, mesh_name, allowEmptyMissing(mesh_name)) | |
handgear_preset = loadAsync(brts.vanityGear, preset_name, allowEmptyMissing(preset_name)) | |
end | |
items[#items + 1] = futureCall(bindHandGear, side, initData, handgear, handgear_mesh, handgear_preset, hand_colors, | |
initData.commonAssets.degMap, initData.commonAssets.degMask) | |
end | |
----------------------------------------------------------------------------- | |
local function bindShoe(side, initData, shoe, shoe_mesh, shoe_preset, spats_preset, shoe_colors, spats_colors, degMap, degMask) | |
local item_name = string.format("playerShoe%s", side.prefix) | |
local item = createItem(item_name, shoe.slot, initData.laneId, 1) | |
if shoe_mesh then | |
item:addMeshLodPair(lod0, shoe_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
local addShaderParams = function(material) | |
-- presets | |
if shoe_preset then | |
material:addPreset(shoe_preset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- vectors | |
if shoe_colors then | |
material:addVector("primaryColor", shoe_colors.primary) | |
material:addVector("secondaryColor", shoe_colors.secondary) | |
material:addVector("tertiaryColor", shoe_colors.tertiary) | |
material:addVector("quaternaryColor", shoe_colors.quaternary) | |
end | |
end | |
local spat_materials = { | |
["Black"] = {0.015, 0.015, 0.015, 1.0}, -- on the 0-255 scale, this is roughly 4 | |
["White"] = {0.92156, 0.92156, 0.92156, 1.0}, -- on the 0-255 scale, this is 235 | |
["TeamColor"] = initData.UniformPrimaryColor, | |
["SecondaryColor"] = initData.UniformSecondaryColor | |
} | |
local addSpatShaderParams = function(material) | |
--reuse preset logic for spats since the whole model uses one material | |
addShaderParams(material) | |
if not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout then | |
-- NFL | |
material:addVector("comboColor", spat_materials[shoe.spatmaterial] or spat_materials["White"]) | |
elseif spats_color then | |
-- Vanity | |
material:addVector("comboColor", spats_colors.primary) | |
else | |
--Vanity Fallback | |
material:addVector("comboColor", spat_materials["White"]) | |
end | |
end | |
item:reserveMaterials(6) | |
addShaderParams(item:addMaterial(string.format("playerShoe%s_lod0_mat", side.prefix))) | |
addShaderParams(item:addMaterial(string.format("playerShoe%s_lod1_mat", side.prefix))) | |
addShaderParams(item:addMaterial(string.format("playerShoe%s_lod2_mat", side.prefix))) | |
addSpatShaderParams(item:addMaterial(string.format("playerSpat%s_lod0_mat", side.prefix))) | |
addSpatShaderParams(item:addMaterial(string.format("playerSpat%s_lod1_mat", side.prefix))) | |
addSpatShaderParams(item:addMaterial(string.format("playerSpat%s_lod2_mat", side.prefix))) | |
-- vanity thin spats using incorrect material name, just going to accept | |
addSpatShaderParams(item:addMaterial(string.format("playerSpats%s_lod0_mat", side.prefix))) | |
addSpatShaderParams(item:addMaterial(string.format("playerSpats%s_lod1_mat", side.prefix))) | |
addSpatShaderParams(item:addMaterial(string.format("playerSpats%s_lod2_mat", side.prefix))) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadShoe(side, items, initData) | |
local shoe_mesh = nil | |
local shoe_preset = nil | |
local spats_preset = nil -- currently unused as material is not seperated for shoes but in the future custom spat shaders might be supported | |
local shoe_colors = nil | |
local spats_colors = nil | |
local shoe = { | |
slot = isLeft(side) and slots.shoeL or slots.shoeR, | |
model = isLeft(side) and initData.LeftShoeModel or initData.RightShoeModel, | |
material = isLeft(side) and initData.LeftShoeMaterial or initData.RightShoeMaterial, | |
spatmaterial = isLeft(side) and initData.LeftSpatMaterial or initData.RightSpatMaterial, | |
palette = isLeft(side) and initData.LeftShoePalette or initData.RightShoePalette, | |
loadoutAsset = nil, | |
loadoutOverrides = nil, | |
} | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout) then | |
shoe_colors = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
local shoeModelTemp = shoe.model | |
local shoePresetTemp = shoe.material | |
if string.lower(initData.UniqueHeadName) == "kaepernickcolin_10578" then | |
shoeModelTemp = "shoe_low_NikeVaporEdge99Club" | |
end | |
local mesh_name = string.format("%s%s_metamorph;shoe_Mid_NikeLunarBeast%s_metamorph", | |
shoe.model, side.prefix, | |
side.prefix) | |
local material_var = "" | |
if initData.ShoesPreset then | |
material_var = initData.ShoesPreset:match("_[A-Za-z]*$"):lower() | |
end | |
if string.lower(initData.UniqueHeadName) == "kaepernickcolin_10578" then | |
shoeModelTemp = "shoe_low_NikeVaporEdge_BLMKaepernick" | |
shoePresetTemp = "" | |
end | |
local preset_name = string.format("%s%s%s_preset;%s%s_preset", | |
shoe.model, shoe.material, material_var, | |
shoe.model, shoe.material) | |
shoe_mesh = loadAsync(brts.gear, mesh_name, AllowMissing) | |
shoe_preset = loadAsync(brts.presets, preset_name, AllowMissing) | |
else | |
local shoe_side = isLeft(side) and "LeftShoe" or "RightShoe" | |
local spats_side = "LeftSpat" | |
--spats_side = isLeft(side) and "LeftSpat" or "RightSpat" --only use Left side for spats as we do not support indepedendent spat selection, uncomment this to enable per-side behavior | |
shoe_colors = resolveVanityColors(initData, initData.vanityItemData[shoe_side]) | |
spats_colors = resolveVanityColors(initData, initData.vanityItemData[spats_side]) | |
local spats_model = initData.vanityItemData[spats_side].Model | |
local mesh_name = string.format("%s%s%s_metamorph", initData.vanityItemData[shoe_side].Model, spats_model, side.prefix) | |
local preset_name = string.format("%s%s%s_preset;%s%s_preset;%s_preset", initData.vanityItemData[shoe_side].Material, spats_model, side.prefix, initData.vanityItemData[shoe_side].Model, side.prefix, initData.vanityItemData[shoe_side].Material) | |
shoe_mesh = loadAsync(brts.vanityGear, mesh_name, AllowMissing) | |
shoe_preset = loadAsync(brts.vanityGear, preset_name, AllowMissing) | |
--spats_preset = loadAsync(brts.vanityGear, spats_preset_name, true) | |
end | |
items[#items + 1] = futureCall(bindShoe, side, initData, shoe, shoe_mesh, shoe_preset, spats_preset, shoe_colors, spats_colors, | |
initData.commonAssets.degMap, initData.commonAssets.degMask) | |
end | |
----------------------------------------------------------------------------- | |
local function bindWristGear(side, initData, wristgear, wristgear_mesh, wristgear_preset, wrist_colors, degMap, degMask) | |
local item_name = string.format("playerWristGear%s", side.prefix) | |
local item = createItem(item_name, wristgear.slot, initData.laneId, 1) | |
if wristgear_mesh then | |
item:addMeshLodPair(lod0, wristgear_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
local addShaderParams = function(material) | |
-- presets | |
if wristgear_preset then | |
material:addPreset(wristgear_preset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- vectors | |
if wrist_colors then | |
material:addVector("primaryColor", wrist_colors.primary) | |
material:addVector("secondaryColor", wrist_colors.secondary) | |
material:addVector("tertiaryColor", wrist_colors.tertiary) | |
material:addVector("quaternaryColor", wrist_colors.quaternary) | |
end | |
end | |
item:reserveMaterials(3) | |
addShaderParams(item:addMaterial(string.format("playerWrist%s_lod0_mat", side.prefix))) | |
addShaderParams(item:addMaterial(string.format("playerWrist%s_lod1_mat", side.prefix))) | |
addShaderParams(item:addMaterial(string.format("playerWrist%s_lod2_mat", side.prefix))) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadWristGear(side, items, initData) | |
local wristgear_mesh = nil | |
local wristgear_preset = nil | |
local wristgear = { | |
slot = isLeft(side) and slots.wristgearL or slots.wristgearR, | |
model = isLeft(side) and initData.LeftWristModel or initData.RightWristModel, | |
material = isLeft(side) and initData.LeftWristMaterial or initData.RightWristMaterial, | |
loadoutAsset = nil, | |
loadoutOverrides = nil, | |
} | |
local wrist_colors = nil | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout) then | |
wrist_colors = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
local mesh_name = string.format("%s%s_metamorph;wrist%s_metamorph", wristgear.model, side.prefix, side.prefix) | |
local preset_name = string.format("%s_%s_preset;%s_preset;player_missing_preset", | |
wristgear.model, wristgear.material, | |
wristgear.model) | |
wristgear_mesh = loadAsync(brts.armgear, mesh_name, AllowMissing) | |
wristgear_preset = loadAsync(brts.presets, preset_name) | |
else | |
local wrist_side = isLeft(side) and "LeftWrist" or "RightWrist" | |
wrist_colors = resolveVanityColors(initData, initData.vanityItemData[wrist_side]) | |
local mesh_name = string.format("%s%s_metamorph", initData.vanityItemData[wrist_side].Model, side.prefix) | |
local preset_name = string.format("%s%s_preset;%s%s_preset", initData.vanityItemData[wrist_side].Material, side.prefix, initData.vanityItemData[wrist_side].Model, side.prefix) | |
wristgear_mesh = loadAsync(brts.vanityGear, mesh_name, AllowMissing) | |
wristgear_preset = loadAsync(brts.vanityGear, preset_name, AllowMissing) | |
end | |
items[#items + 1] = futureCall(bindWristGear, side, initData, wristgear, wristgear_mesh, wristgear_preset, wrist_colors, | |
initData.commonAssets.degMap, initData.commonAssets.degMask) | |
end | |
----------------------------------------------------------------------------- | |
local function bindMouthpiece(initData, mouthpiece_mesh, mouthpiece_preset, mouthpiece_colors, degMap, degMask) | |
local item = createItem("playerMouthpiece", slots.mouthpiece, initData.laneId, 1) | |
item:setIncludeCullTagHashes("Mouthpiece") | |
local addShaderParams = function(material) | |
-- presets | |
if mouthpiece_preset then | |
material:addPreset(mouthpiece_preset) | |
end | |
-- degradation | |
addDegShaderParams(material, initData, degMap, degMask) | |
-- palettization | |
if mouthpiece_colors then | |
material:addVector("primaryColor", mouthpiece_colors.primary) | |
material:addVector("secondaryColor", mouthpiece_colors.secondary) | |
material:addVector("tertiaryColor", mouthpiece_colors.tertiary) | |
material:addVector("quaternaryColor", mouthpiece_colors.quaternary) | |
end | |
end | |
--Mesh | |
if mouthpiece_mesh then | |
item:addMeshLodPair(lod0, mouthpiece_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
item:reserveMaterials(3) | |
addShaderParams(item:addMaterial("mouthpiece_lod0_mat")) | |
addShaderParams(item:addMaterial("mouthpiece_lod1_mat")) | |
addShaderParams(item:addMaterial("mouthpiece_lod2_mat")) | |
end | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadMouthpiece(items, initData) | |
local mouthpiece_mesh = nil | |
local mouthpiece_preset = nil | |
local mouthpiece_colors = nil | |
if (not initData.Vanity or not initData.Vanity.VanityOnFieldLoadout) then | |
mouthpiece_colors = { | |
primary = initData.UniformPrimaryColor, | |
secondary = initData.UniformSecondaryColor, | |
tertiary = initData.UniformTertiaryColor, | |
quaternary = initData.UniformSecondaryColor, | |
} | |
local mesh_name = string.format("mouthpiece_%s", initData.MouthpieceModel) | |
local preset_name = string.format("mouthpiece_%s%s_preset", initData.MouthpieceModel, initData.MouthpieceMaterial) | |
mouthpiece_mesh = loadAsync(brts.headgear, mesh_name, true) --block mouthpieces in NFL on request | |
mouthpiece_preset = loadAsync(brts.headgear, preset_name, true) | |
else | |
mouthpiece_colors = resolveVanityColors(initData, initData.vanityItemData.Mouthpiece) | |
local mouthpiece_model = initData.vanityItemData.Mouthpiece.Model | |
local mouthpiece_material = initData.vanityItemData.Mouthpiece.Material | |
local mesh_name = string.format("%s", mouthpiece_model) | |
local preset_name = string.format("%s_preset; mouthpiece_preset", mouthpiece_material) | |
mouthpiece_mesh = loadAsync(brts.vanityGear, mesh_name, true) | |
mouthpiece_preset = loadAsync(brts.vanityGear, preset_name, true) | |
end | |
items[#items + 1] = futureCall(bindMouthpiece, initData, mouthpiece_mesh, mouthpiece_preset, mouthpiece_colors, | |
initData.commonAssets.degMap, initData.commonAssets.degMask) | |
end | |
----------------------------------------------------------------------------- | |
local function bindShadow(shadow_mesh, shadowRtw_mesh, laneId) | |
local item = createItem("playerShadow", slots.shadow, laneId, 2) | |
item:addMeshLodPair(lod0, shadow_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
if shadowRtw_mesh then | |
item:addMeshLodPair(lod0, shadowRtw_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
end | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadShadow(items, initData) | |
local shadow_mesh = loadAsync(brts.shadow, "playerShadow") | |
local shadowRtw_mesh = loadAsync(brts.shadow, "playerShadow_rtwImportance", true) | |
items[#items + 1] = futureCall(bindShadow, shadow_mesh, shadowRtw_mesh, initData.laneId) | |
end | |
----------------------------------------------------------------------------- | |
local function bindZOnly(zonly_mesh, laneId) | |
local item = createItem("PlayerZOnly", slots.zonly, laneId, 1) | |
item:addMeshLodPair(lod0, zonly_mesh, updateBoundingBox, playerDrawOrder, playerDrawSubOrder) | |
return item | |
end | |
----------------------------------------------------------------------------- | |
local function loadZOnly(items, initData) | |
local zonly_mesh = loadAsync(brts.zonly, "MeshCombineZOnly") | |
items[#items + 1] = futureCall(bindZOnly, zonly_mesh, initData.laneId) | |
end | |
-- =========================================================================================================================================================== | |
-- BODY LOGIC | |
function LoadPlayer(initData, laneId) | |
local items = {} | |
local generatedTextures = {} | |
local assets = {} | |
log("Start LoadPlayer: " .. initData.JerseyName .. " (index: " .. initData.RosterIndex .. ", lane: " .. laneId .. ")") | |
-- Debug use, see | |
-- https://confluence.ea.com/pages/viewpage.action?spaceKey=madden&title=Football+DB+Messaging+-+aka+Roster+and+Appearance+Tweaker | |
if initData.vanityItemData and initData.vanityItemData.Info then | |
log('Vanity requests: ' .. initData.vanityItemData.requestedVanityItems .. ' # Resolved: ' .. initData.vanityItemData.resolvedVanityItems .. " for " .. initData.vanityItemData.Info) | |
else | |
log("No Vanity Found for " .. initData.JerseyName .. " (index: " .. initData.RosterIndex .. ")") | |
end | |
--log_table(initData.vanityItemData) | |
initData.laneId = laneId | |
initData.commonAssets = loadCommonAssets(initData) | |
--log("VANITY DEBUG TABLE") | |
--log_table(initData) | |
if DrawEnabled("Hair", initData) then | |
-- EA_TODO: This is placeholder logic. We actually want to eventually load both assets. For now, just load the strand hair if it exists and is enabled. | |
if SETTING_EnableStrandHair then | |
loadStrandHair(items, initData) | |
end | |
loadHair(items, initData) | |
end | |
if DrawEnabled("Head", initData) then | |
loadHead(items, initData) | |
end | |
if DrawEnabled("HeadGear", initData) then | |
loadHeadGear(items, initData) | |
end | |
if DrawEnabled("Pants", initData) then | |
loadPants(items, initData) | |
end | |
if DrawEnabled("Legs", initData) then | |
loadLegs(items, initData) | |
end | |
if DrawEnabled("Torso", initData) then | |
loadTorso(items, generatedTextures, initData) | |
end | |
if DrawEnabled("Arms", initData) then | |
loadArms(items, initData) | |
end | |
if DrawEnabled("LeftElbow", initData) then | |
loadElbowGear(LeftSide, items, initData) | |
end | |
if DrawEnabled("RightElbow", initData) then | |
loadElbowGear(RightSide, items, initData) | |
end | |
if DrawEnabled("LeftHandGear", initData) then | |
loadHandGear(LeftSide, items, initData) | |
end | |
if DrawEnabled("RightHandGear", initData) then | |
loadHandGear(RightSide, items, initData) | |
end | |
if DrawEnabled("LeftShoe", initData) then | |
loadShoe(LeftSide, items, initData) | |
end | |
if DrawEnabled("RightShoe", initData) then | |
loadShoe(RightSide, items, initData) | |
end | |
if DrawEnabled("LeftWrist", initData) then | |
loadWristGear(LeftSide, items, initData) | |
end | |
if DrawEnabled("RightWrist", initData) then | |
loadWristGear(RightSide, items, initData) | |
end | |
if DrawEnabled("Mouthpiece", initData) then | |
loadMouthpiece(items, initData) | |
end | |
if DrawEnabled("Shadow", initData) then | |
loadShadow(items, initData) | |
end | |
if DrawEnabled("ZOnly", initData) then | |
loadZOnly(items, initData) | |
end | |
log("End LoadPlayer: " .. initData.JerseyName .. " (index: " .. initData.RosterIndex .. ")") | |
return items, generatedTextures, assets | |
end | |
function PrintGlobal() | |
log("Lua _G contents start:") | |
for n in pairs(_G) do log(n) end | |
log("Lua _G contents end") | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment