DefineClass.BlendEntityObj = { __parents = { "Object" }, properties = { { category = "Blend", id = "BlendEntity1", name = "Entity 1", editor = "choice", default = "Human_Head_M_As_01", items = function (obj) return obj:GetBlendEntityList() end }, { category = "Blend", id = "BlendWeight1", name = "Weight 1", editor = "number", default = 50, slider = true, min = 0, max = 100 }, { category = "Blend", id = "BlendEntity2", name = "Entity 2", editor = "choice", default = "", items = function (obj) return obj:GetBlendEntityList() end }, { category = "Blend", id = "BlendWeight2", name = "Weight 2", editor = "number", default = 0, slider = true, min = 0, max = 100 }, { category = "Blend", id = "BlendEntity3", name = "Entity 3", editor = "choice", default = "", items = function (obj) return obj:GetBlendEntityList() end }, { category = "Blend", id = "BlendWeight3", name = "Weight 3", editor = "number", default = 0, slider = true, min = 0, max = 100 }, }, entity = "Human_Head_M_Placeholder_01", } function BlendEntityObj:GetBlendEntityList() return { "" } end local g_UpdateBlendObjs = {} local g_UpdateBlendEntityThread = false function GetEntityIdleMaterial(entity) return entity and entity ~= "" and GetStateMaterial(entity, "idle") or "" end function BlendEntityObj:UpdateBlendInternal() if (not self.BlendEntity1 or self.BlendWeight1 == 0) and (not self.BlendEntity2 or self.BlendWeight2 == 0) and (not self.BlendEntity3 or self.BlendWeight3 == 0) then return end local err = AsyncMeshBlend(self.entity, 0, self.BlendEntity1, self.BlendWeight1, self.BlendEntity2, self.BlendWeight2, self.BlendEntity3, self.BlendWeight3) if err then print("Failed to blend meshes: ", err) end do local mat0 = GetEntityIdleMaterial(self.entity) local mat1 = GetEntityIdleMaterial(self.BlendEntity1) local mat2 = GetEntityIdleMaterial(self.BlendEntity2) local mat3 = GetEntityIdleMaterial(self.BlendEntity3) assert(mat0 ~= mat1 and mat0 ~= mat2 and mat0 ~= mat3) end local sumBlends = self.BlendWeight1 + self.BlendWeight2 + self.BlendWeight2 local blend2, blend3 = 0, 0 if sumBlends ~= self.BlendWeight1 then blend2 = self.BlendWeight2 * 100 / (sumBlends - self.BlendWeight1) blend3 = self.BlendWeight3 * 100 / sumBlends end SetMaterialBlendMaterials(GetEntityIdleMaterial(self.entity), GetEntityIdleMaterial(self.BlendEntity1), blend2, GetEntityIdleMaterial(self.BlendEntity2), blend3, GetEntityIdleMaterial(self.BlendEntity3)) self:ChangeEntity(self.entity) end function BlendEntityObj:UpdateBlend() g_UpdateBlendObjs[self] = true if not g_UpdateBlendEntityThread then g_UpdateBlendEntityThread = CreateRealTimeThread(function() while true do local obj, v = next(g_UpdateBlendObjs) if obj == nil then break end g_UpdateBlendObjs[obj] = nil obj:UpdateBlendInternal() end g_UpdateBlendEntityThread = false end) end end function BlendEntityObj:OnEditorSetProperty(prop_id, old_value, ged) if prop_id == "BlendEntity1" or prop_id == "BlendEntity2" or prop_id == "BlendEntity3" or prop_id == "BlendWeight1" or prop_id == "BlendWeight2" or prop_id == "BlendWeight3" then self:UpdateBlend() end end function BlendTest() local obj = BlendEntityObj:new() obj:SetPos(GetTerrainCursor()) ViewObject(obj) editor.ClearSel() editor.AddToSel({obj}) OpenGedGameObjectEditor(editor.GetSel()) return obj end function BlendMatTest(weight2, weight3) local obj = PlaceObj("Jacket_Nylon_M_Slim_01") obj:SetPos(GetTerrainCursor()) ViewObject(obj) editor.ClearSel() editor.AddToSel({obj}) local blendEntity1 = "Jacket_Nylon_M_Slim_01" local blendEntity2 = "Jacket_Nylon_M_Skinny_01" local blendEntity3 = "Jacket_Nylon_M_Chubby_01" weight2 = weight2 or 50 weight3 = weight3 or 25 SetMaterialBlendMaterials(GetEntityIdleMaterial(obj:GetEntity()), GetEntityIdleMaterial(blendEntity1), weight2, GetEntityIdleMaterial(blendEntity2), weight3, GetEntityIdleMaterial(blendEntity3)) return obj end