1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00

Merge branch 'master' into master

This commit is contained in:
DustyBagel 2024-09-03 02:28:40 -05:00 committed by GitHub
commit 8a841aee59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
328 changed files with 8044 additions and 10079 deletions

45
.github/workflows/whitespace_checks.yml vendored Normal file
View file

@ -0,0 +1,45 @@
name: whitespace_checks
# Check whitespaces of the following file types
# Not checked: .lua, .yml, .properties, .conf, .java, .py, .svg, .gradle, .xml, ...
# (luacheck already checks .lua files)
on:
push:
paths:
- '**.txt'
- '**.md'
- '**.[ch]'
- '**.cpp'
- '**.hpp'
- '**.sh'
- '**.cmake'
- '**.glsl'
pull_request:
paths:
- '**.txt'
- '**.md'
- '**.[ch]'
- '**.cpp'
- '**.hpp'
- '**.sh'
- '**.cmake'
- '**.glsl'
jobs:
trailing_whitespaces:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Line endings are already ensured by .gitattributes
- name: Check trailing whitespaces
run: if git ls-files | grep -E '\.txt$|\.md$|\.[ch]$|\.cpp$|\.hpp$|\.sh$|\.cmake$|\.glsl$' | xargs grep -n '\s$'; then echo -e "\033[0;31mFound trailing whitespace"; (exit 1); else (exit 0); fi
tabs_lua_api_files:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Some files should not contain tabs
- name: Check tabs in Lua API files
run: if grep -n $'\t' doc/lua_api.md doc/client_lua_api.md; then echo -e "\033[0;31mFound tab in markdown file"; (exit 1); else (exit 0); fi

View file

@ -37,6 +37,12 @@ files["builtin/client/register.lua"] = {
}
}
files["builtin/common/math.lua"] = {
globals = {
"math",
},
}
files["builtin/common/misc_helpers.lua"] = {
globals = {
"dump", "dump2", "table", "math", "string",
@ -46,7 +52,7 @@ files["builtin/common/misc_helpers.lua"] = {
}
files["builtin/common/vector.lua"] = {
globals = { "vector" },
globals = { "vector", "math" },
}
files["builtin/game/voxelarea.lua"] = {

View file

@ -283,6 +283,8 @@ if(BUILD_UNITTESTS OR BUILD_BENCHMARKS)
add_subdirectory(lib/catch2)
endif()
add_subdirectory(lib/tiniergltf)
# Subdirectories
# Be sure to add all relevant definitions above this
add_subdirectory(src)

View file

@ -8,7 +8,7 @@ android {
compileSdk 34
targetSdkVersion 34
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
versionCode project.versionCode
versionCode versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild
}
buildFeatures {
@ -116,18 +116,6 @@ clean {
delete new File("src/main/assets", "Minetest.zip")
}
// Map for the version code that gives each ABI a value.
import com.android.build.OutputFile
def abiCodes = ['armeabi-v7a': 0, 'arm64-v8a': 1]
android.applicationVariants.all { variant ->
variant.outputs.each {
output ->
def abiName = output.getFilter(OutputFile.ABI)
output.versionCodeOverride = abiCodes.get(abiName, 0) + variant.versionCode
}
}
dependencies {
implementation project(':native')
implementation 'androidx.appcompat:appcompat:1.6.1'

View file

@ -1,13 +1,12 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
project.ext.set("versionMajor", 5) // Version Major
project.ext.set("versionMinor", 10) // Version Minor
project.ext.set("versionMinor", 10) // Version Minor
project.ext.set("versionPatch", 0) // Version Patch
// ^ keep in sync with cmake
project.ext.set("versionCode", 48) // Android Version Code
// NOTE: +2 after each release!
// +1 for ARM and +1 for ARM64 APK's, because
// each APK must have a larger `versionCode` than the previous
project.ext.set("versionBuild", 0) // Version Build
// ^ fourth version number to allow releasing Android-only fixes and beta versions
buildscript {
ext.ndk_version = '26.2.11394342'

View file

@ -8,7 +8,7 @@ android {
compileSdk 34
targetSdkVersion 34
externalNativeBuild {
cmake {
cmake {
arguments "-DANDROID_STL=c++_shared",
"-DENABLE_CURL=1", "-DENABLE_SOUND=1",
"-DENABLE_GETTEXT=1",

View file

@ -69,7 +69,7 @@ local function build_chatcommands_formspec(name, sel, copy)
description = cmds[2].description
if copy then
local msg = S("Command: @1 @2",
core.colorize("#0FF", "/" .. cmds[1]), cmds[2].params)
core.colorize("#0FF", (INIT == "client" and "." or "/") .. cmds[1]), cmds[2].params)
if INIT == "client" then
core.display_chat_message(msg)
else

41
builtin/common/math.lua Normal file
View file

@ -0,0 +1,41 @@
--[[
Math utils.
--]]
function math.hypot(x, y)
return math.sqrt(x * x + y * y)
end
function math.sign(x, tolerance)
tolerance = tolerance or 0
if x > tolerance then
return 1
elseif x < -tolerance then
return -1
end
return 0
end
function math.factorial(x)
assert(x % 1 == 0 and x >= 0, "factorial expects a non-negative integer")
if x >= 171 then
-- 171! is greater than the biggest double, no need to calculate
return math.huge
end
local v = 1
for k = 2, x do
v = v * k
end
return v
end
function math.round(x)
if x < 0 then
local int = math.ceil(x)
local frac = x - int
return int - ((frac <= -0.5) and 1 or 0)
end
local int = math.floor(x)
local frac = x - int
return int + ((frac >= 0.5) and 1 or 0)
end

View file

@ -3,6 +3,7 @@
--------------------------------------------------------------------------------
-- Localize functions to avoid table lookups (better performance).
local string_sub, string_find = string.sub, string.find
local math = math
--------------------------------------------------------------------------------
local function basic_dump(o)
@ -220,47 +221,6 @@ function string:trim()
return self:match("^%s*(.-)%s*$")
end
--------------------------------------------------------------------------------
function math.hypot(x, y)
return math.sqrt(x * x + y * y)
end
--------------------------------------------------------------------------------
function math.sign(x, tolerance)
tolerance = tolerance or 0
if x > tolerance then
return 1
elseif x < -tolerance then
return -1
end
return 0
end
--------------------------------------------------------------------------------
function math.factorial(x)
assert(x % 1 == 0 and x >= 0, "factorial expects a non-negative integer")
if x >= 171 then
-- 171! is greater than the biggest double, no need to calculate
return math.huge
end
local v = 1
for k = 2, x do
v = v * k
end
return v
end
function math.round(x)
if x < 0 then
local int = math.ceil(x)
local frac = x - int
return int - ((frac <= -0.5) and 1 or 0)
end
local int = math.floor(x)
local frac = x - int
return int + ((frac >= 0.5) and 1 or 0)
end
local formspec_escapes = {
["\\"] = "\\\\",
["["] = "\\[",
@ -702,6 +662,7 @@ function core.privs_to_string(privs, delim)
list[#list + 1] = priv
end
end
table.sort(list)
return table.concat(list, delim)
end

View file

@ -1,6 +1,7 @@
_G.core = {}
_G.vector = {metatable = {}}
dofile("builtin/common/math.lua")
dofile("builtin/common/vector.lua")
dofile("builtin/common/misc_helpers.lua")

View file

@ -0,0 +1,16 @@
_G.core = {}
dofile("builtin/common/math.lua")
describe("math", function()
it("round()", function()
assert.equal(0, math.round(0))
assert.equal(10, math.round(10.3))
assert.equal(11, math.round(10.5))
assert.equal(11, math.round(10.7))
assert.equal(-10, math.round(-10.3))
assert.equal(-11, math.round(-10.5))
assert.equal(-11, math.round(-10.7))
assert.equal(0, math.round(0.49999999999999994))
assert.equal(0, math.round(-0.49999999999999994))
end)
end)

View file

@ -1,4 +1,5 @@
_G.core = {}
dofile("builtin/common/math.lua")
dofile("builtin/common/vector.lua")
dofile("builtin/common/misc_helpers.lua")

View file

@ -1,4 +1,5 @@
_G.vector = {}
dofile("builtin/common/math.lua")
dofile("builtin/common/vector.lua")
describe("vector", function()
@ -113,12 +114,35 @@ describe("vector", function()
assert.equal(vector.new(0, 1, -1), a:round())
end)
it("ceil()", function()
local a = vector.new(0.1, 0.9, -0.5)
assert.equal(vector.new(1, 1, 0), vector.ceil(a))
assert.equal(vector.new(1, 1, 0), a:ceil())
end)
it("sign()", function()
local a = vector.new(-120.3, 0, 231.5)
assert.equal(vector.new(-1, 0, 1), vector.sign(a))
assert.equal(vector.new(-1, 0, 1), a:sign())
assert.equal(vector.new(0, 0, 1), vector.sign(a, 200))
assert.equal(vector.new(0, 0, 1), a:sign(200))
end)
it("abs()", function()
local a = vector.new(-123.456, 0, 13)
assert.equal(vector.new(123.456, 0, 13), vector.abs(a))
assert.equal(vector.new(123.456, 0, 13), a:abs())
end)
it("apply()", function()
local i = 0
local f = function(x)
i = i + 1
return x + i
end
local f2 = function(x, opt1, opt2, opt3)
return x + opt1 + opt2 + opt3
end
local a = vector.new(0.1, 0.9, -0.5)
assert.equal(vector.new(1, 1, 0), vector.apply(a, math.ceil))
assert.equal(vector.new(1, 1, 0), a:apply(math.ceil))
@ -126,6 +150,9 @@ describe("vector", function()
assert.equal(vector.new(0.1, 0.9, 0.5), a:apply(math.abs))
assert.equal(vector.new(1.1, 2.9, 2.5), vector.apply(a, f))
assert.equal(vector.new(4.1, 5.9, 5.5), a:apply(f))
local b = vector.new(1, 2, 3)
assert.equal(vector.new(4, 5, 6), vector.apply(b, f2, 1, 1, 1))
assert.equal(vector.new(4, 5, 6), b:apply(f2, 1, 1, 1))
end)
it("combine()", function()
@ -469,4 +496,13 @@ describe("vector", function()
assert.True(vector.in_area(vector.new(-10, -10, -10), vector.new(-10, -10, -10), vector.new(10, 10, 10)))
assert.False(vector.in_area(vector.new(-10, -10, -10), vector.new(10, 10, 10), vector.new(-11, -10, -10)))
end)
it("random_in_area()", function()
local min = vector.new(-100, -100, -100)
local max = vector.new(100, 100, 100)
for i = 1, 1000 do
local random = vector.random_in_area(min, max)
assert.True(vector.in_area(random, min, max))
end
end)
end)

View file

@ -5,6 +5,7 @@ Note: The vector.*-functions must be able to accept old vectors that had no meta
-- localize functions
local setmetatable = setmetatable
local math = math
vector = {}
@ -97,18 +98,26 @@ function vector.floor(v)
end
function vector.round(v)
return fast_new(
math.round(v.x),
math.round(v.y),
math.round(v.z)
)
return vector.apply(v, math.round)
end
function vector.apply(v, func)
function vector.ceil(v)
return vector.apply(v, math.ceil)
end
function vector.sign(v, tolerance)
return vector.apply(v, math.sign, tolerance)
end
function vector.abs(v)
return vector.apply(v, math.abs)
end
function vector.apply(v, func, ...)
return fast_new(
func(v.x),
func(v.y),
func(v.z)
func(v.x, ...),
func(v.y, ...),
func(v.z, ...)
)
end
@ -387,6 +396,14 @@ function vector.random_direction()
return fast_new(x/l, y/l, z/l)
end
function vector.random_in_area(min, max)
return fast_new(
math.random(min.x, max.x),
math.random(min.y, max.y),
math.random(min.z, max.z)
)
end
if rawget(_G, "core") and core.set_read_vector and core.set_push_vector then
local function read_vector(v)
return v.x, v.y, v.z

View file

@ -19,7 +19,7 @@
local BASE_SPACING = 0.1
local function get_scroll_btn_width()
return core.settings:get_bool("enable_touch") and 0.8 or 0.5
return core.settings:get_bool("touch_gui") and 0.8 or 0.5
end
local function buttonbar_formspec(self)

View file

@ -221,6 +221,7 @@ core.register_chatcommand("haspriv", {
return true, S("No online player has the \"@1\" privilege.",
param)
else
table.sort(players_with_priv)
return true, S("Players online with the \"@1\" privilege: @2",
param,
table.concat(players_with_priv, ", "))

View file

@ -42,6 +42,7 @@ core.features = {
node_interaction_actor = true,
moveresult_new_pos = true,
override_item_remove_fields = true,
hotbar_hud_element = true,
}
function core.has_feature(arg)

View file

@ -251,11 +251,31 @@ register_builtin_hud_element("minimap", {
position = {x = 1, y = 0},
alignment = {x = -1, y = 1},
offset = {x = -10, y = 10},
size = {x = 256, y = 256},
size = {x = 0, y = -25},
},
show_elem = function(player, flags)
local proto_ver = core.get_player_information(player:get_player_name()).protocol_version
-- Don't add a minimap for clients which already have it hardcoded in C++.
return flags.minimap and
core.get_player_information(player:get_player_name()).protocol_version >= 44
return flags.minimap and proto_ver >= 44
end,
update_def = function(player, elem_def)
local proto_ver = core.get_player_information(player:get_player_name()).protocol_version
-- Only use percentage when the client supports it.
elem_def.size = proto_ver >= 45 and {x = 0, y = -25} or {x = 256, y = 256}
end,
})
--- Hotbar
register_builtin_hud_element("hotbar", {
elem_def = {
type = "hotbar",
position = {x = 0.5, y = 1},
direction = 0,
alignment = {x = 0, y = -1},
offset = {x = 0, y = -4}, -- Extra padding below.
},
show_elem = function(player, flags)
return flags.hotbar
end,
})

View file

@ -42,6 +42,7 @@ local scriptdir = core.get_builtin_path()
local commonpath = scriptdir .. "common" .. DIR_DELIM
local asyncpath = scriptdir .. "async" .. DIR_DELIM
dofile(commonpath .. "math.lua")
dofile(commonpath .. "vector.lua")
dofile(commonpath .. "strict.lua")
dofile(commonpath .. "serialize.lua")

View file

@ -181,7 +181,7 @@ local function get_info_formspec(text)
return table.concat({
"formspec_version[6]",
"size[15.75,9.5]",
core.settings:get_bool("enable_touch") and "padding[0.01,0.01]" or "position[0.5,0.55]",
core.settings:get_bool("touch_gui") and "padding[0.01,0.01]" or "position[0.5,0.55]",
"label[4,4.35;", text, "]",
"container[0,", H - 0.8 - 0.375, "]",
@ -212,7 +212,7 @@ local function get_formspec(dlgdata)
local formspec = {
"formspec_version[6]",
"size[15.75,9.5]",
core.settings:get_bool("enable_touch") and "padding[0.01,0.01]" or "position[0.5,0.55]",
core.settings:get_bool("touch_gui") and "padding[0.01,0.01]" or "position[0.5,0.55]",
"style[status,downloading,queued;border=false]",
@ -463,7 +463,7 @@ end
local function handle_events(event)
if event == "DialogShow" then
-- On touchscreen, don't show the "MINETEST" header behind the dialog.
mm_game_theme.set_engine(core.settings:get_bool("enable_touch"))
mm_game_theme.set_engine(core.settings:get_bool("touch_gui"))
-- If ContentDB is already loaded, auto-install packages here.
do_auto_install()

View file

@ -22,13 +22,13 @@ end
local function get_loading_formspec()
local ENABLE_TOUCH = core.settings:get_bool("enable_touch")
local w = ENABLE_TOUCH and 14 or 7
local TOUCH_GUI = core.settings:get_bool("touch_gui")
local w = TOUCH_GUI and 14 or 7
local formspec = {
"formspec_version[3]",
"size[", w, ",9.05]",
ENABLE_TOUCH and "padding[0.01,0.01]" or "position[0.5,0.55]",
TOUCH_GUI and "padding[0.01,0.01]" or "position[0.5,0.55]",
"label[3,4.525;", fgettext("Loading..."), "]",
}
return table.concat(formspec)
@ -110,18 +110,18 @@ local function get_formspec(data)
message_bg = mt_color_orange
end
local ENABLE_TOUCH = core.settings:get_bool("enable_touch")
local TOUCH_GUI = core.settings:get_bool("touch_gui")
local w = ENABLE_TOUCH and 14 or 7
local w = TOUCH_GUI and 14 or 7
local padded_w = w - 2*0.375
local dropdown_w = ENABLE_TOUCH and 10.2 or 4.25
local dropdown_w = TOUCH_GUI and 10.2 or 4.25
local button_w = (padded_w - 0.25) / 3
local button_pad = button_w / 2
local formspec = {
"formspec_version[3]",
"size[", w, ",9.05]",
ENABLE_TOUCH and "padding[0.01,0.01]" or "position[0.5,0.55]",
TOUCH_GUI and "padding[0.01,0.01]" or "position[0.5,0.55]",
"style[title;border=false]",
"box[0,0;", w, ",0.8;#3333]",
"button[0,0;", w, ",0.8;title;", fgettext("Install $1", package.title) , "]",

View file

@ -0,0 +1,85 @@
{
"#": "https://github.com/orgs/minetest/teams/engine/members",
"core_developers": [
"Perttu Ahola (celeron55) <celeron55@gmail.com> [Project founder]",
"sfan5 <sfan5@live.de>",
"ShadowNinja <shadowninja@minetest.net>",
"Nathanaëlle Courant (Nore/Ekdohibs) <nore@mesecons.net>",
"Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>",
"Andrew Ward (rubenwardy) <rw@rubenwardy.com>",
"Krock/SmallJoker <mk939@ymail.com>",
"Lars Hofhansl <larsh@apache.org>",
"v-rob <robinsonvincent89@gmail.com>",
"Desour/DS",
"srifqi",
"Gregor Parzefall (grorp)",
"Lars Müller (luatic)"
],
"previous_core_developers": [
"BlockMen",
"Maciej Kasatkin (RealBadAngel) [RIP]",
"Lisa Milne (darkrose) <lisa@ltmnet.com>",
"proller",
"Ilya Zhuravlev (xyz) <xyz@minetest.net>",
"PilzAdam <pilzadam@minetest.net>",
"est31 <MTest31@outlook.com>",
"kahrl <kahrl@gmx.net>",
"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
"sapier",
"Zeno",
"Auke Kok (sofar) <sofar@foo-projects.org>",
"Aaron Suen <warr1024@gmail.com>",
"paramat",
"Pierre-Yves Rollo <dev@pyrollo.com>",
"hecks",
"Jude Melton-Houghton (TurkeyMcMac) [RIP]",
"Hugues Ross <hugues.ross@gmail.com>",
"Dmitry Kostenko (x2048) <codeforsmile@gmail.com>"
],
"#": "Currently only https://github.com/orgs/minetest/teams/triagers/members",
"core_team": [
"Zughy [Issue triager]",
"wsor [Issue triager]",
"Hugo Locurcio (Calinou) [Issue triager]"
],
"#": "For updating active/previous contributors, see the script in ./util/gather_git_credits.py",
"contributors": [
"cx384",
"numzero",
"AFCMS",
"sfence",
"Wuzzy",
"ROllerozxa",
"JosiahWI",
"OgelGames",
"David Heidelberg",
"1F616EMO",
"HybridDog",
"Bradley Pierce (Thresher)",
"savilli",
"Stvk imension",
"y5nw",
"chmodsayshello",
"jordan4ibanez",
"superfloh247"
],
"previous_contributors": [
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest logo]",
"red-001 <red-001@outlook.ie>",
"Giuseppe Bilotta",
"HybridDog",
"ClobberXD",
"Dániel Juhász (juhdanad) <juhdanad@gmail.com>",
"MirceaKitsune <mirceakitsune@gmail.com>",
"Jean-Patrick Guerrero (kilbith)",
"MoNTE48",
"Constantin Wenger (SpeedProg)",
"Ciaran Gultnieks (CiaranG)",
"Paul Ouellette (pauloue)",
"stujones11",
"Rogier <rogier777@gmail.com>",
"Gregory Currie (gregorycu)",
"JacobF",
"Jeija <jeija@mesecons.net>"
]
}

View file

@ -126,7 +126,7 @@ local function get_formspec(data)
local retval =
"size[11.5,7.5,true]" ..
"label[0.5,0;" .. fgettext("World:") .. "]" ..
"label[1.75,0;" .. data.worldspec.name .. "]"
"label[1.75,0;" .. core.formspec_escape(data.worldspec.name) .. "]"
if mod.is_modpack or mod.type == "game" then
local info = core.formspec_escape(

View file

@ -110,7 +110,7 @@ local function load()
local change_keys = {
query_text = "Controls",
requires = {
keyboard_mouse = true,
touch_controls = false,
},
get_formspec = function(self, avail_w)
local btn_w = math.min(avail_w, 3)
@ -324,8 +324,6 @@ local function check_requirements(name, requires)
local special = {
android = PLATFORM == "Android",
desktop = PLATFORM ~= "Android",
touchscreen_gui = core.settings:get_bool("enable_touch"),
keyboard_mouse = not core.settings:get_bool("enable_touch"),
shaders_support = shaders_support,
shaders = core.settings:get_bool("enable_shaders") and shaders_support,
opengl = video_driver == "opengl",
@ -457,13 +455,13 @@ local function get_formspec(dialogdata)
local extra_h = 1 -- not included in tabsize.height
local tabsize = {
width = core.settings:get_bool("enable_touch") and 16.5 or 15.5,
height = core.settings:get_bool("enable_touch") and (10 - extra_h) or 12,
width = core.settings:get_bool("touch_gui") and 16.5 or 15.5,
height = core.settings:get_bool("touch_gui") and (10 - extra_h) or 12,
}
local scrollbar_w = core.settings:get_bool("enable_touch") and 0.6 or 0.4
local scrollbar_w = core.settings:get_bool("touch_gui") and 0.6 or 0.4
local left_pane_width = core.settings:get_bool("enable_touch") and 4.5 or 4.25
local left_pane_width = core.settings:get_bool("touch_gui") and 4.5 or 4.25
local left_pane_padding = 0.25
local search_width = left_pane_width + scrollbar_w - (0.75 * 2)
@ -477,7 +475,7 @@ local function get_formspec(dialogdata)
local fs = {
"formspec_version[6]",
"size[", tostring(tabsize.width), ",", tostring(tabsize.height + extra_h), "]",
core.settings:get_bool("enable_touch") and "padding[0.01,0.01]" or "",
core.settings:get_bool("touch_gui") and "padding[0.01,0.01]" or "",
"bgcolor[#0000]",
-- HACK: this is needed to allow resubmitting the same formspec
@ -652,15 +650,15 @@ local function buttonhandler(this, fields)
write_settings_early()
end
-- enable_touch is a checkbox in a setting component. We handle this
-- touch_controls is a checkbox in a setting component. We handle this
-- setting differently so we can hide/show pages using the next if-statement
if fields.enable_touch ~= nil then
local value = core.is_yes(fields.enable_touch)
core.settings:set_bool("enable_touch", value)
if fields.touch_controls ~= nil then
local value = core.is_yes(fields.touch_controls)
core.settings:set_bool("touch_controls", value)
write_settings_early()
end
if fields.show_advanced ~= nil or fields.enable_touch ~= nil then
if fields.show_advanced ~= nil or fields.touch_controls ~= nil then
local suggested_page_id = update_filtered_pages(dialogdata.query)
dialogdata.components = nil

View file

@ -15,96 +15,6 @@
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-- https://github.com/orgs/minetest/teams/engine/members
local core_developers = {
"Perttu Ahola (celeron55) <celeron55@gmail.com> [Project founder]",
"sfan5 <sfan5@live.de>",
"ShadowNinja <shadowninja@minetest.net>",
"Nathanaëlle Courant (Nore/Ekdohibs) <nore@mesecons.net>",
"Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>",
"Andrew Ward (rubenwardy) <rw@rubenwardy.com>",
"Krock/SmallJoker <mk939@ymail.com>",
"Lars Hofhansl <larsh@apache.org>",
"v-rob <robinsonvincent89@gmail.com>",
"Desour/DS",
"srifqi",
"Gregor Parzefall (grorp)",
"Lars Müller (luatic)",
}
-- currently only https://github.com/orgs/minetest/teams/triagers/members
local core_team = {
"Zughy [Issue triager]",
"wsor [Issue triager]",
"Hugo Locurcio (Calinou) [Issue triager]",
}
-- For updating active/previous contributors, see the script in ./util/gather_git_credits.py
local active_contributors = {
"cx384",
"numzero",
"AFCMS",
"sfence",
"Wuzzy",
"ROllerozxa",
"JosiahWI",
"OgelGames",
"David Heidelberg",
"1F616EMO",
"HybridDog",
"Bradley Pierce (Thresher)",
"savilli",
"Stvk imension",
"y5nw",
"chmodsayshello",
"jordan4ibanez",
"superfloh247",
}
local previous_core_developers = {
"BlockMen",
"Maciej Kasatkin (RealBadAngel) [RIP]",
"Lisa Milne (darkrose) <lisa@ltmnet.com>",
"proller",
"Ilya Zhuravlev (xyz) <xyz@minetest.net>",
"PilzAdam <pilzadam@minetest.net>",
"est31 <MTest31@outlook.com>",
"kahrl <kahrl@gmx.net>",
"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
"sapier",
"Zeno",
"Auke Kok (sofar) <sofar@foo-projects.org>",
"Aaron Suen <warr1024@gmail.com>",
"paramat",
"Pierre-Yves Rollo <dev@pyrollo.com>",
"hecks",
"Jude Melton-Houghton (TurkeyMcMac) [RIP]",
"Hugues Ross <hugues.ross@gmail.com>",
"Dmitry Kostenko (x2048) <codeforsmile@gmail.com>",
}
local previous_contributors = {
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest logo]",
"red-001 <red-001@outlook.ie>",
"Giuseppe Bilotta",
"HybridDog",
"ClobberXD",
"Dániel Juhász (juhdanad) <juhdanad@gmail.com>",
"MirceaKitsune <mirceakitsune@gmail.com>",
"Jean-Patrick Guerrero (kilbith)",
"MoNTE48",
"Constantin Wenger (SpeedProg)",
"Ciaran Gultnieks (CiaranG)",
"Paul Ouellette (pauloue)",
"stujones11",
"Rogier <rogier777@gmail.com>",
"Gregory Currie (gregorycu)",
"JacobF",
"Jeija <jeija@mesecons.net>",
}
local function prepare_credits(dest, source)
local string = table.concat(source, "\n") .. "\n"
@ -120,6 +30,13 @@ local function prepare_credits(dest, source)
table.insert(dest, string)
end
local function get_credits()
local f = assert(io.open(core.get_mainmenu_path() .. "/credits.json"))
local json = core.parse_json(f:read("*all"))
f:close()
return json
end
return {
name = "about",
caption = fgettext("About"),
@ -133,30 +50,32 @@ return {
"<tag name=gray color=#aaa>",
}
local credits = get_credits()
table.insert_all(hypertext, {
"<heading>", fgettext_ne("Core Developers"), "</heading>\n",
})
prepare_credits(hypertext, core_developers)
prepare_credits(hypertext, credits.core_developers)
table.insert_all(hypertext, {
"\n",
"<heading>", fgettext_ne("Core Team"), "</heading>\n",
})
prepare_credits(hypertext, core_team)
prepare_credits(hypertext, credits.core_team)
table.insert_all(hypertext, {
"\n",
"<heading>", fgettext_ne("Active Contributors"), "</heading>\n",
})
prepare_credits(hypertext, active_contributors)
prepare_credits(hypertext, credits.contributors)
table.insert_all(hypertext, {
"\n",
"<heading>", fgettext_ne("Previous Core Developers"), "</heading>\n",
})
prepare_credits(hypertext, previous_core_developers)
prepare_credits(hypertext, credits.previous_core_developers)
table.insert_all(hypertext, {
"\n",
"<heading>", fgettext_ne("Previous Contributors"), "</heading>\n",
})
prepare_credits(hypertext, previous_contributors)
prepare_credits(hypertext, credits.previous_contributors)
hypertext = table.concat(hypertext):sub(1, -2)

View file

@ -94,7 +94,7 @@ function singleplayer_refresh_gamebar()
local btnbar = buttonbar_create(
"game_button_bar",
core.settings:get_bool("enable_touch") and {x = 0, y = 7.25} or {x = 0, y = 7.475},
core.settings:get_bool("touch_gui") and {x = 0, y = 7.25} or {x = 0, y = 7.475},
{x = 15.5, y = 1.25},
"#000000",
game_buttonbar_button_handler)

View file

@ -61,7 +61,7 @@
#
# # This is a comment
# #
# # Requires: shaders, enable_dynamic_shadows, !touchscreen_gui
# # Requires: shaders, enable_dynamic_shadows, !touch_controls
# name (Readable name) type type_args
#
# A requirement can be the name of a boolean setting or an engine-defined value.
@ -72,7 +72,6 @@
# * shaders_support (a video driver that supports shaders, may not be enabled)
# * shaders (both enable_shaders and shaders_support)
# * desktop / android
# * touchscreen_gui / keyboard_mouse
# * opengl / gles
# * You can negate any requirement by prepending with !
#
@ -92,7 +91,7 @@ camera_smoothing (Camera smoothing) float 0.0 0.0 0.99
# Smooths rotation of camera when in cinematic mode, 0 to disable. Enter cinematic mode by using the key set in Controls.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
cinematic_camera_smoothing (Camera smoothing in cinematic mode) float 0.7 0.0 0.99
# If enabled, you can place nodes at the position (feet + eye level) where you stand.
@ -113,7 +112,7 @@ always_fly_fast (Always fly fast) bool true
# The time in seconds it takes between repeated node placements when holding
# the place button.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
repeat_place_time (Place repetition interval) float 0.25 0.16 2.0
# The minimum time in seconds it takes between digging nodes when holding
@ -132,62 +131,60 @@ safe_dig_and_place (Safe digging and placing) bool false
# Invert vertical mouse movement.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
invert_mouse (Invert mouse) bool false
# Mouse sensitivity multiplier.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
mouse_sensitivity (Mouse sensitivity) float 0.2 0.001 10.0
# Enable mouse wheel (scroll) for item selection in hotbar.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
enable_hotbar_mouse_wheel (Hotbar: Enable mouse wheel for selection) bool true
# Invert mouse wheel (scroll) direction for item selection in hotbar.
#
# Requires: keyboard_mouse
# Requires: !touch_controls
invert_hotbar_mouse_wheel (Hotbar: Invert mouse wheel direction) bool false
[*Touchscreen]
# Enables touchscreen mode, allowing you to play the game with a touchscreen.
#
# Requires: !android
enable_touch (Enable touchscreen) bool true
# Enables the touchscreen controls, allowing you to play the game with a touchscreen.
touch_controls (Enable touchscreen controls) bool true
# Touchscreen sensitivity multiplier.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touchscreen_sensitivity (Touchscreen sensitivity) float 0.2 0.001 10.0
# The length in pixels after which a touch interaction is considered movement.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touchscreen_threshold (Movement threshold) int 20 0 100
# The delay in milliseconds after which a touch interaction is considered a long tap.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touch_long_tap_delay (Threshold for long taps) int 400 100 1000
# Use crosshair to select object instead of whole screen.
# If enabled, a crosshair will be shown and will be used for selecting object.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touch_use_crosshair (Use crosshair for touch screen) bool false
# Fixes the position of virtual joystick.
# If disabled, virtual joystick will center to first-touch's position.
#
# Requires: touchscreen_gui
# Requires: touch_controls
fixed_virtual_joystick (Fixed virtual joystick) bool false
# Use virtual joystick to trigger "Aux1" button.
# If enabled, virtual joystick will also tap "Aux1" button when out of main circle.
#
# Requires: touchscreen_gui
# Requires: touch_controls
virtual_joystick_triggers_aux1 (Virtual joystick triggers Aux1 button) bool false
# The gesture for punching players/entities.
@ -200,7 +197,7 @@ virtual_joystick_triggers_aux1 (Virtual joystick triggers Aux1 button) bool fals
# Known from the classic Minetest mobile controls.
# Combat is more or less impossible.
#
# Requires: touchscreen_gui
# Requires: touch_controls
touch_punch_gesture (Punch gesture) enum short_tap short_tap,long_tap
@ -687,6 +684,10 @@ language (Language) enum ,be,bg,ca,cs,da,de,el,en,eo,es,et,eu,fi,fr,gd,gl,hu,i
[**GUI]
# When enabled, the GUI is optimized to be more usable on touchscreens.
# Whether this is enabled by default depends on your hardware form-factor.
touch_gui (Optimize GUI for touchscreens) bool false
# Scale GUI by a user specified value.
# Use a nearest-neighbor-anti-alias filter to scale the GUI.
# This will smooth over some of the rough edges, and blend
@ -735,6 +736,12 @@ hud_scaling (HUD scaling) float 1.0 0.5 20
# Mods may still set a background.
show_nametag_backgrounds (Show name tag backgrounds by default) bool true
# Whether to show the client debug info (has the same effect as hitting F5).
show_debug (Show debug info) bool false
# Radius to use when the block bounds HUD feature is set to near blocks.
show_block_bounds_radius_near (Block bounds HUD radius) int 4 0 1000
[**Chat]
# Maximum number of recent chat messages to show
@ -1848,11 +1855,11 @@ shader_path (Shader path) path
# The rendering back-end.
# Note: A restart is required after changing this!
# OpenGL is the default for desktop, and OGLES2 for Android.
# Shaders are supported by everything but OGLES1.
video_driver (Video driver) enum ,opengl,opengl3,ogles1,ogles2
video_driver (Video driver) enum ,opengl,opengl3,ogles2
# Distance in nodes at which transparency depth sorting is enabled
# Use this to limit the performance impact of transparency depth sorting
# Distance in nodes at which transparency depth sorting is enabled.
# Use this to limit the performance impact of transparency depth sorting.
# Set to 0 to disable it entirely.
transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
# Radius of cloud area stated in number of 64 node cloud squares.
@ -2012,9 +2019,6 @@ client_unload_unused_data_timeout (Mapblock unload timeout) float 600.0 0.0
# Set to -1 for unlimited amount.
client_mapblock_limit (Mapblock limit) int 7500 -1 2147483647
# Whether to show the client debug info (has the same effect as hitting F5).
show_debug (Show debug info) bool false
# Maximum number of blocks that are simultaneously sent per client.
# The maximum total count is calculated dynamically:
# max_total = ceil((#clients + max_users) * per_client / 4)
@ -2024,9 +2028,8 @@ max_simultaneous_block_sends_per_client (Maximum simultaneous block sends per cl
# This determines how long they are slowed down after placing or removing a node.
full_block_send_enable_min_time_from_building (Delay in sending blocks after building) float 2.0 0.0
# Maximum number of packets sent per send step, if you have a slow connection
# try reducing it, but don't reduce it to a number below double of targeted
# client number.
# Maximum number of packets sent per send step in the low-level networking code.
# You generally don't need to change this, however busy servers may benefit from a higher number.
max_packets_per_iteration (Max. packets per iteration) int 1024 1 65535
# Compression level to use when sending mapblocks to the client.

View file

@ -1 +0,0 @@
../../irr/media/Shaders

View file

@ -58,11 +58,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define FXAA_SPAN_MAX 8.0
#endif
//optimized version for mobile, where dependent
//optimized version for mobile, where dependent
//texture reads can be a bottleneck
vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 inverseVP,
vec2 v_rgbNW, vec2 v_rgbNE,
vec2 v_rgbSW, vec2 v_rgbSE,
vec2 v_rgbNW, vec2 v_rgbNE,
vec2 v_rgbSW, vec2 v_rgbSE,
vec2 v_rgbM) {
vec4 color;
vec3 rgbNW = texture2D(tex, v_rgbNW).xyz;
@ -111,6 +111,6 @@ void main(void)
{
vec2 uv = varTexCoord.st;
gl_FragColor = fxaa(rendered, uv, texelSize0,
gl_FragColor = fxaa(rendered, uv, texelSize0,
sampleNW, sampleNE, sampleSW, sampleSE, uv);
}

View file

@ -12,7 +12,7 @@ varying vec2 sampleSW;
varying vec2 sampleSE;
/*
Based on
Based on
https://github.com/mattdesl/glsl-fxaa/
Portions Copyright (c) 2011 by Armin Ronacher.
*/

View file

@ -11,7 +11,7 @@ if(ENABLE_LUAJIT)
find_package(LuaJIT)
if(LUAJIT_FOUND)
set(USE_LUAJIT TRUE)
message (STATUS "Using LuaJIT provided by system.")
message (STATUS "Using LuaJIT")
elseif(REQUIRE_LUAJIT)
message(FATAL_ERROR "LuaJIT not found whereas REQUIRE_LUAJIT=\"TRUE\" is used.\n"
"To continue, either install LuaJIT or do not use REQUIRE_LUAJIT=\"TRUE\".")

View file

@ -315,7 +315,7 @@ Call these functions only at load time!
* `minetest.register_globalstep(function(dtime))`
* Called every client environment step
* `dtime` is the time since last execution in seconds.
* `dtime` is the time since last execution in seconds.
* `minetest.register_on_mods_loaded(function())`
* Called just after mods have finished loading.
* `minetest.register_on_shutdown(function())`
@ -586,9 +586,9 @@ Call these functions only at load time!
* `minetest.camera`
* Reference to the camera object. See [`Camera`](#camera) class reference for methods.
* `minetest.show_formspec(formname, formspec)` : returns true on success
* Shows a formspec to the player
* Shows a formspec to the player
* `minetest.display_chat_message(message)` returns true on success
* Shows a chat message to the current player.
* Shows a chat message to the current player.
Setting-related
---------------
@ -866,9 +866,9 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
-----------------
### Definitions
* `minetest.get_node_def(nodename)`
* Returns [node definition](#node-definition) table of `nodename`
* Returns [node definition](#node-definition) table of `nodename`
* `minetest.get_item_def(itemstring)`
* Returns item definition table of `itemstring`
* Returns item definition table of `itemstring`
#### Node Definition
@ -971,10 +971,10 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
```lua
{
address = "minetest.example.org", -- The domain name/IP address of a remote server or "" for a local server.
ip = "203.0.113.156", -- The IP address of the server.
port = 30000, -- The port the client is connected to.
protocol_version = 30 -- Will not be accurate at start up as the client might not be connected to the server yet, in that case it will be 0.
address = "minetest.example.org", -- The domain name/IP address of a remote server or "" for a local server.
ip = "203.0.113.156", -- The IP address of the server.
port = 30000, -- The port the client is connected to.
protocol_version = 30 -- Will not be accurate at start up as the client might not be connected to the server yet, in that case it will be 0.
}
```

View file

@ -14,7 +14,7 @@ It is highly recommended to use vcpkg as package manager.
After you successfully built vcpkg you can easily install the required libraries:
```powershell
vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext sdl2 --triplet x64-windows
vcpkg install zlib zstd curl[winssl] openal-soft libvorbis libogg libjpeg-turbo sqlite3 freetype luajit gmp jsoncpp gettext[tools] sdl2 --triplet x64-windows
```
- `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
@ -52,7 +52,7 @@ Use `--triplet` to specify the target triplet, e.g. `x64-windows` or `x86-window
Run the following script in PowerShell:
```powershell
cmake . -G"Visual Studio 15 2017 Win64" -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GETTEXT=OFF -DENABLE_CURSES=OFF
cmake . -G"Visual Studio 16 2019" -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_CURSES=OFF
cmake --build . --config Release
```
Make sure that the right compiler is selected and the path to the vcpkg toolchain is correct.

View file

@ -274,7 +274,7 @@ Accepted formats are:
images: .png, .jpg, .tga, (deprecated:) .bmp
sounds: .ogg vorbis
models: .x, .b3d, .obj
models: .x, .b3d, .obj, .gltf (Minetest 5.10 or newer)
Other formats won't be sent to the client (e.g. you can store .blend files
in a folder for convenience, without the risk that such files are transferred)
@ -291,6 +291,43 @@ in one of its parents, the parent's file is used.
Although it is discouraged, a mod can overwrite a media file of any mod that it
depends on by supplying a file with an equal name.
Only a subset of model file format features is supported:
Simple textured meshes (with multiple textures), optionally with normals.
The .x and .b3d formats additionally support skeletal animation.
#### glTF
The glTF model file format for now only serves as a
more modern alternative to the other static model file formats;
it unlocks no special rendering features.
This means that many glTF features are not supported *yet*, including:
* Animation
* Cameras
* Materials
* Only base color textures are supported
* Backface culling is overridden
* Double-sided materials don't work
* Alternative means of supplying data
* Embedded images
* References to files via URIs
Textures are supplied solely via the same means as for the other model file formats:
The `textures` object property, the `tiles` node definition field and
the list of textures used in the `model[]` formspec element.
The order in which textures are to be supplied
is that in which they appear in the `textures` array in the glTF file.
Do not rely on glTF features not being supported; they may be supported in the future.
The backwards compatibility guarantee does not extend to ignoring unsupported features.
For example, if your model used an emissive material,
you should expect that a future version of Minetest may respect this,
and thus cause your model to render differently there.
Naming conventions
------------------
@ -1744,6 +1781,13 @@ Displays a horizontal bar made up of half-images with an optional background.
* `item`: Position of item that is selected.
* `direction`: Direction the list will be displayed in
* `offset`: offset in pixels from position.
* `alignment`: The alignment of the inventory. Aligned at the top left corner if not specified.
### `hotbar`
* `direction`: Direction the list will be displayed in
* `offset`: offset in pixels from position.
* `alignment`: The alignment of the inventory.
### `waypoint`
@ -1802,6 +1846,11 @@ Displays a minimap on the HUD.
* `size`: Size of the minimap to display. Minimap should be a square to avoid
distortion.
* Negative values represent percentages of the screen. If either `x` or `y`
is specified as a percentage, the resulting pixel size will be used for
both `x` and `y`. Example: On a 1920x1080 screen, `{x = 0, y = -25}` will
result in a 270x270 minimap.
* Negative values are supported starting with protocol version 45.
* `alignment`: The alignment of the minimap.
* `offset`: offset in pixels from position.
@ -2625,6 +2674,9 @@ background elements are drawn before all other elements.
**WARNING**: do _not_ use an element name starting with `key_`; those names are
reserved to pass key press events to formspec!
**WARNING**: names and values of elements cannot contain binary data such as ASCII
control characters. For values, escape sequences used by the engine are an exception to this.
**WARNING**: Minetest allows you to add elements to every single formspec instance
using `player:set_formspec_prepend()`, which may be the reason backgrounds are
appearing when you don't expect them to, or why things are styled differently
@ -2861,14 +2913,14 @@ Elements
* Requires formspec version >= 6.
* See `background9[]` documentation for more information.
### `model[<X>,<Y>;<W>,<H>;<name>;<mesh>;<textures>;<rotation X,Y>;<continuous>;<mouse control>;<frame loop range>;<animation speed>]`
### `model[<X>,<Y>;<W>,<H>;<name>;<mesh>;<textures>;<rotation>;<continuous>;<mouse control>;<frame loop range>;<animation speed>]`
* Show a mesh model.
* `name`: Element name that can be used for styling
* `mesh`: The mesh model to use.
* `textures`: The mesh textures to use according to the mesh materials.
Texture names must be separated by commas.
* `rotation {X,Y}` (Optional): Initial rotation of the camera.
* `rotation` (Optional): Initial rotation of the camera, format `x,y`.
The axes are euler angles in degrees.
* `continuous` (Optional): Whether the rotation is continuous. Default `false`.
* `mouse control` (Optional): Whether the model can be controlled with the mouse. Default `true`.
@ -3658,7 +3710,7 @@ Player Inventory lists
* `hand`: list containing an override for the empty hand
* Is not created automatically, use `InvRef:set_size`
* Is only used to enhance the empty hand's tool capabilities
Custom lists can be added and deleted with `InvRef:set_size(name, size)` like
any other inventory.
@ -3847,15 +3899,23 @@ vectors are written like this: `(x, y, z)`:
* If `v` has zero length, returns `(0, 0, 0)`.
* `vector.floor(v)`:
* Returns a vector, each dimension rounded down.
* `vector.ceil(v)`:
* Returns a vector, each dimension rounded up.
* `vector.round(v)`:
* Returns a vector, each dimension rounded to nearest integer.
* At a multiple of 0.5, rounds away from zero.
* `vector.apply(v, func)`:
* `vector.sign(v, tolerance)`:
* Returns a vector where `math.sign` was called for each component.
* See [Helper functions] for details.
* `vector.abs(v)`:
* Returns a vector with absolute values for each component.
* `vector.apply(v, func, ...)`:
* Returns a vector where the function `func` has been applied to each
component.
* `...` are optional arguments passed to `func`.
* `vector.combine(v, w, func)`:
* Returns a vector where the function `func` has combined both components of `v` and `w`
for each component
* Returns a vector where the function `func` has combined both components of `v` and `w`
for each component
* `vector.equals(v1, v2)`:
* Returns a boolean, `true` if the vectors are identical.
* `vector.sort(v1, v2)`:
@ -3873,10 +3933,14 @@ vectors are written like this: `(x, y, z)`:
by a `vector.*` function.
* Returns `false` for anything else, including tables like `{x=3,y=1,z=4}`.
* `vector.in_area(pos, min, max)`:
* Returns a boolean value indicating if `pos` is inside area formed by `min` and `max`.
* `min` and `max` are inclusive.
* If `min` is bigger than `max` on some axis, function always returns false.
* You can use `vector.sort` if you have two vectors and don't know which are the minimum and the maximum.
* Returns a boolean value indicating if `pos` is inside area formed by `min` and `max`.
* `min` and `max` are inclusive.
* If `min` is bigger than `max` on some axis, function always returns false.
* You can use `vector.sort` if you have two vectors and don't know which are the minimum and the maximum.
* `vector.random_in_area(min, max)`:
* Returns a random integer position in area formed by `min` and `max`
* `min` and `max` are inclusive.
* You can use `vector.sort` if you have two vectors and don't know which are the minimum and the maximum.
For the following functions `x` can be either a vector or a number:
@ -5076,12 +5140,12 @@ Callbacks:
used for updating the entity state.
* `on_deactivate(self, removal)`
* Called when the object is about to get removed or unloaded.
* `removal`: boolean indicating whether the object is about to get removed.
Calling `object:remove()` on an active object will call this with `removal=true`.
The mapblock the entity resides in being unloaded will call this with `removal=false`.
* Note that this won't be called if the object hasn't been activated in the first place.
In particular, `minetest.clear_objects({mode = "full"})` won't call this,
whereas `minetest.clear_objects({mode = "quick"})` might call this.
* `removal`: boolean indicating whether the object is about to get removed.
Calling `object:remove()` on an active object will call this with `removal=true`.
The mapblock the entity resides in being unloaded will call this with `removal=false`.
* Note that this won't be called if the object hasn't been activated in the first place.
In particular, `minetest.clear_objects({mode = "full"})` won't call this,
whereas `minetest.clear_objects({mode = "quick"})` might call this.
* `on_step(self, dtime, moveresult)`
* Called on every server tick, after movement and collision processing.
* `dtime`: elapsed time since last call
@ -5456,6 +5520,8 @@ Utilities
moveresult_new_pos = true,
-- Allow removing definition fields in `minetest.override_item` (5.9.0)
override_item_remove_fields = true,
-- The predefined hotbar is a Lua HUD element of type `hotbar` (5.10.0)
hotbar_hud_element = true,
}
```
@ -5723,7 +5789,7 @@ Call these functions only at load time!
* `minetest.register_globalstep(function(dtime))`
* Called every server step, usually interval of 0.1s.
* `dtime` is the time since last execution in seconds.
* `dtime` is the time since last execution in seconds.
* `minetest.register_on_mods_loaded(function())`
* Called after mods have finished loading and before the media is cached or the
aliases handled.
@ -6151,7 +6217,7 @@ Environment access
* **Warning**: The same warning as for `minetest.get_objects_inside_radius` applies.
Use `minetest.objects_in_area` instead to iterate only valid objects.
* `minetest.objects_in_area(min_pos, max_pos)`
* returns an iterator of valid objects
* returns an iterator of valid objects
* `minetest.set_timeofday(val)`: set time of day
* `val` is between `0` and `1`; `0` for midnight, `0.5` for midday
* `minetest.get_timeofday()`: get time of day
@ -6463,7 +6529,8 @@ Formspec
* `playername`: name of player to show formspec
* `formname`: name passed to `on_player_receive_fields` callbacks.
It should follow the `"modname:<whatever>"` naming convention.
`formname` must not be empty.
* `formname` must not be empty, unless you want to reshow
the inventory formspec without updating it for future opens.
* `formspec`: formspec to display
* `minetest.close_formspec(playername, formname)`
* `playername`: name of player to close formspec
@ -7101,7 +7168,7 @@ Misc.
could be used as a player name (regardless of whether said player exists).
* `minetest.hud_replace_builtin(name, hud_definition)`
* Replaces definition of a builtin hud element
* `name`: `"breath"`, `"health"` or `"minimap"`
* `name`: `"breath"`, `"health"`, `"minimap"` or `"hotbar"`
* `hud_definition`: definition to replace builtin definition
* `minetest.parse_relative_number(arg, relative_to)`: returns number or nil
* Helper function for chat commands.
@ -7961,13 +8028,13 @@ child will follow movement and rotation of that bone.
object.
* `set_detach()`: Detaches object. No-op if object was not attached.
* `set_bone_position([bone, position, rotation])`
* Shorthand for `set_bone_override(bone, {position = position, rotation = rotation:apply(math.rad)})` using absolute values.
* **Note:** Rotation is in degrees, not radians.
* **Deprecated:** Use `set_bone_override` instead.
* Shorthand for `set_bone_override(bone, {position = position, rotation = rotation:apply(math.rad)})` using absolute values.
* **Note:** Rotation is in degrees, not radians.
* **Deprecated:** Use `set_bone_override` instead.
* `get_bone_position(bone)`: returns the previously set position and rotation of the bone
* Shorthand for `get_bone_override(bone).position.vec, get_bone_override(bone).rotation.vec:apply(math.deg)`.
* **Note:** Returned rotation is in degrees, not radians.
* **Deprecated:** Use `get_bone_override` instead.
* Shorthand for `get_bone_override(bone).position.vec, get_bone_override(bone).rotation.vec:apply(math.deg)`.
* **Note:** Returned rotation is in degrees, not radians.
* **Deprecated:** Use `get_bone_override` instead.
* `set_bone_override(bone, override)`
* `bone`: string
* `override`: `{ position = property, rotation = property, scale = property }` or `nil`
@ -7984,7 +8051,7 @@ child will follow movement and rotation of that bone.
* Compatibility note: Clients prior to 5.9.0 only support absolute position and rotation.
All values are treated as absolute and are set immediately (no interpolation).
* `get_bone_override(bone)`: returns `override` in the above format
* **Note:** Unlike `get_bone_position`, the returned rotation is in radians, not degrees.
* **Note:** Unlike `get_bone_position`, the returned rotation is in radians, not degrees.
* `get_bone_overrides()`: returns all bone overrides as table `{[bonename] = override, ...}`
* `set_properties(object property table)`
* `get_properties()`: returns a table of all object properties
@ -8081,8 +8148,8 @@ child will follow movement and rotation of that bone.
* Fifth column: subject viewed from above
* Sixth column: subject viewed from below
* `get_luaentity()`:
* Returns the object's associated luaentity table, if there is one
* Otherwise returns `nil` (e.g. for players)
* Returns the object's associated luaentity table, if there is one
* Otherwise returns `nil` (e.g. for players)
* `get_entity_name()`:
* **Deprecated**: Will be removed in a future version,
use `:get_luaentity().name` instead.
@ -8494,6 +8561,14 @@ child will follow movement and rotation of that bone.
* Result is a table with the same fields as `light_definition` in `set_lighting`.
* `respawn()`: Respawns the player using the same mechanism as the death screen,
including calling `on_respawnplayer` callbacks.
* `get_flags()`: returns a table of player flags (the following boolean fields):
* `breathing`: Whether breathing (regaining air) is enabled, default `true`.
* `drowning`: Whether drowning (losing air) is enabled, default `true`.
* `node_damage`: Whether the player takes damage from nodes, default `true`.
* `set_flags(flags)`: sets flags
* takes a table in the same format as returned by `get_flags`
* absent fields are left unchanged
`PcgRandom`
-----------
@ -8669,7 +8744,7 @@ In multiplayer mode, the error may be arbitrarily large.
Interface for the operating system's crypto-secure PRNG.
It can be created via `SecureRandom()`. The constructor returns nil if a
It can be created via `SecureRandom()`. The constructor throws an error if a
secure random device cannot be found on the system.
### Methods
@ -8940,7 +9015,7 @@ Player properties need to be saved manually.
Entity definition
-----------------
Used by `minetest.register_entity`.
Used by `minetest.register_entity`.
The entity definition table becomes a metatable of a newly created per-entity
luaentity table, meaning its fields (e.g. `initial_properties`) will be shared
between all instances of an entity.
@ -10640,8 +10715,9 @@ Used by `ObjectRef:hud_add`. Returned by `ObjectRef:hud_get`.
```lua
{
type = "image",
-- Type of element, can be "image", "text", "statbar", "inventory",
-- "waypoint", "image_waypoint", "compass" or "minimap"
-- Type of element, can be "compass", "hotbar" (46 ¹), "image", "image_waypoint",
-- "inventory", "minimap" (44 ¹), "statbar", "text" or "waypoint"
-- ¹: minimal protocol version for client-side support
-- If undefined "text" will be used.
hud_elem_type = "image",
@ -10987,7 +11063,7 @@ Types used are defined in the previous section.
* vec3 range `acc`: the direction and speed with which the particle
accelerates
* vec3 range `size`: scales the visual size of the particle texture.
* float range `size`: scales the visual size of the particle texture.
if `node` is set, this can be set to 0 to spawn randomly-sized particles
(just like actual node dig particles).

View file

@ -8,6 +8,15 @@ The main menu is defined as a formspec by Lua in `builtin/mainmenu/`
Description of formspec language to show your menu is in `lua_api.md`
Images and 3D models
------
Directory delimiters change according to the OS (e.g. on Unix-like systems
is `/`, on Windows is `\`). When putting an image or a 3D model inside a formspec,
be sure to sanitize it first with `core.formspec_escape(img)`; otherwise,
any resource located in a subpath won't be displayed on OSs using `\` as delimiter.
Callbacks
---------
@ -62,6 +71,12 @@ Functions
Filesystem
----------
To access specific subpaths, use `DIR_DELIM` as a directory delimiter instead
of manually putting one, as different OSs use different delimiters. E.g.
```lua
"my" .. DIR_DELIM .. "custom" .. DIR_DELIM .. "path" -- and not my/custom/path
```
* `core.get_builtin_path()`
* returns path to builtin root
* `core.create_dir(absolute_path)` (possible in async calls)
@ -282,7 +297,7 @@ Package - content which is downloadable from the content db, may or may not be i
```lua
{
mods = "/home/user/.minetest/mods",
share = "/usr/share/minetest/mods",
share = "/usr/share/minetest/mods", -- only provided when RUN_IN_PLACE=0
-- Custom dirs can be specified by the MINETEST_MOD_DIR env variable
["/path/to/custom/dir"] = "/path/to/custom/dir",

View file

@ -394,7 +394,7 @@ Timestamp and node ID mappings were introduced in map format version 29.
* `u8` `name_id_mapping_version`
* Should be zero for map format version 29.
* `u16` `num_name_id_mappings`
* foreach `num_name_id_mappings`:
* `u16` `id`

View file

@ -0,0 +1,14 @@
glTF test model (and corresponding texture) licenses:
* Spider (`gltf_spider.gltf`, `gltf_spider.png`):
* By [archfan7411](https://github.com/archfan7411)
* Licensed under CC0, public domain "wherever public domain carries fewer rights or legal protections"
* Frog (`gltf_frog.gltf`, `gltf_frog.png`):
* By [Susybaka1234](https://sketchfab.com/3d-models/african-clawed-frog-v2-c81152c93948480c931c280d18957358)
* Licensed under CC-BY 4.0
* Snow Man (`gltf_snow_man.gltf`, `gltf_snow_man.png`):
* By [jordan4ibanez](https://github.com/jordan4ibanez)
* Licensed under CC0
* Minimal triangle, triangle without indices (`gltf_minimal_triangle.gltf`, `gltf_triangle_without_indices.gltf`)
* From [the glTF sample model collection](https://github.com/KhronosGroup/glTF-Sample-Models)
* Licensed under CC0 / public domain

View file

@ -0,0 +1,51 @@
local function register_entity(name, textures, backface_culling)
minetest.register_entity("gltf:" .. name, {
initial_properties = {
visual = "mesh",
mesh = "gltf_" .. name .. ".gltf",
textures = textures,
backface_culling = backface_culling,
},
})
end
-- These do not have texture coordinates; they simple render as black surfaces.
register_entity("minimal_triangle", {}, false)
register_entity("triangle_with_vertex_stride", {}, false)
register_entity("triangle_without_indices", {}, false)
do
local cube_textures = {"gltf_cube.png"}
register_entity("blender_cube", cube_textures)
register_entity("blender_cube_scaled", cube_textures)
register_entity("blender_cube_matrix_transform", cube_textures)
end
register_entity("snow_man", {"gltf_snow_man.png"})
register_entity("spider", {"gltf_spider.png"})
-- Note: Model has an animation, but we can use it as a static test nevertheless
-- The claws rendering incorrectly from one side is expected behavior:
-- They use an unsupported double-sided material.
register_entity("frog", {"gltf_frog.png"}, false)
minetest.register_node("gltf:frog", {
description = "glTF frog, but it's a node",
tiles = {{name = "gltf_frog.png", backface_culling = false}},
drawtype = "mesh",
mesh = "gltf_frog.gltf",
})
minetest.register_chatcommand("show_model", {
params = "<model> [textures]",
description = "Show a model (defaults to gltf models, for example '/show_model frog').",
func = function(name, param)
local model, textures = param:match"^(.-)%s+(.+)$"
if not model then
model = "gltf_" .. param .. ".gltf"
textures = "gltf_" .. param .. ".png"
end
minetest.show_formspec(name, "gltf:model", table.concat{
"formspec_version[7]",
"size[10,10]",
"model[0,0;10,10;model;", model, ";", textures, ";0,0;true;true;0,0;0]",
})
end,
})

View file

@ -0,0 +1 @@
{"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"POSITION":0}}]}],"buffers":[{"uri":"data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA","byteLength":36}],"bufferViews":[{"buffer":0,"byteOffset":1,"byteLength":36,"target":34962}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5126,"count":3,"type":"VEC3","max":[1,1,0],"min":[0,0,0]}],"asset":{"version":"2.0"}}

View file

@ -0,0 +1 @@
{

View file

@ -0,0 +1,2 @@
name = gltf
description = Hosts gltf test models, both for the C++ unit tests and for in-game viewing

View file

@ -0,0 +1 @@
{"asset":{"generator":"Khronos glTF Blender I/O v1.7.33","version":"2.0"},"scene":0,"scenes":[{"name":"Scene","nodes":[0]}],"nodes":[{"mesh":0,"name":"Cube","scale":[10,10,10]}],"meshes":[{"name":"Cube.004","primitives":[{"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3}]}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"type":"SCALAR"}],"bufferViews":[{"buffer":0,"byteLength":288,"byteOffset":0},{"buffer":0,"byteLength":288,"byteOffset":288},{"buffer":0,"byteLength":192,"byteOffset":576},{"buffer":0,"byteLength":72,"byteOffset":768}],"buffers":[{"byteLength":840,"uri":"data:application/octet-stream;base64,AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAADAPgAAgD8AAAA+AACAPgAAwD4AAAAAAAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AAADAAkAAAAJAAYACAAKABUACAAVABMAFAAXABEAFAARAA4ADQAPAAQADQAEAAIABwASAAwABwAMAAEAFgALAAUAFgAFABAA"}]}

View file

@ -0,0 +1 @@
{"asset":{"generator":"Khronos glTF Blender I/O v1.7.33","version":"2.0"},"scene":0,"scenes":[{"name":"Scene","nodes":[0]}],"nodes":[{"mesh":0,"name":"Cube","matrix":[1,0,0,0,0,2,0,0,0,0,3,0,4,5,6,1]}],"meshes":[{"name":"Cube.004","primitives":[{"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3}]}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"type":"SCALAR"}],"bufferViews":[{"buffer":0,"byteLength":288,"byteOffset":0},{"buffer":0,"byteLength":288,"byteOffset":288},{"buffer":0,"byteLength":192,"byteOffset":576},{"buffer":0,"byteLength":72,"byteOffset":768}],"buffers":[{"byteLength":840,"uri":"data:application/octet-stream;base64,AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAADAPgAAgD8AAAA+AACAPgAAwD4AAAAAAAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AAADAAkAAAAJAAYACAAKABUACAAVABMAFAAXABEAFAARAA4ADQAPAAQADQAEAAIABwASAAwABwAMAAEAFgALAAUAFgAFABAA"}]}

View file

@ -0,0 +1 @@
{"asset":{"generator":"Khronos glTF Blender I/O v1.7.33","version":"2.0"},"scene":0,"scenes":[{"name":"Scene","nodes":[0]}],"nodes":[{"mesh":0,"name":"Cube","scale":[150,1,21.5]}],"meshes":[{"name":"Cube.004","primitives":[{"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3}]}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"type":"SCALAR"}],"bufferViews":[{"buffer":0,"byteLength":288,"byteOffset":0},{"buffer":0,"byteLength":288,"byteOffset":288},{"buffer":0,"byteLength":192,"byteOffset":576},{"buffer":0,"byteLength":72,"byteOffset":768}],"buffers":[{"byteLength":840,"uri":"data:application/octet-stream;base64,AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAADAPgAAgD8AAAA+AACAPgAAwD4AAAAAAAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AAADAAkAAAAJAAYACAAKABUACAAVABMAFAAXABEAFAARAA4ADQAPAAQADQAEAAIABwASAAwABwAMAAEAFgALAAUAFgAFABAA"}]}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"POSITION":1},"indices":0}]}],"buffers":[{"uri":"data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=","byteLength":44}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":6,"target":34963},{"buffer":0,"byteOffset":8,"byteLength":36,"target":34962}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5123,"count":3,"type":"SCALAR","max":[2],"min":[0]},{"bufferView":1,"byteOffset":0,"componentType":5126,"count":3,"type":"VEC3","max":[1,1,0],"min":[0,0,0]}],"asset":{"version":"2.0"}}

View file

@ -0,0 +1 @@
{"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"POSITION":1},"indices":0}]}],"buffers":[{"uri":"data:application/gltf-buffer;base64,AAAIAAcAAAABAAgAAQAJAAgAAQACAAkAAgAKAAkAAgADAAoAAwALAAoAAwAEAAsABAAMAAsABAAFAAwABQANAAwABQAGAA0AAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAQAAAAAAAAAAAAABAQAAAAAAAAAAAAACAQAAAAAAAAAAAAACgQAAAAAAAAAAAAADAQAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAQAAAgD8AAAAAAABAQAAAgD8AAAAAAACAQAAAgD8AAAAAAACgQAAAgD8AAAAAAADAQAAAgD8AAAAACAAKAAwAAAAAAIA/AAAAQAAAAAAAAEBAAABAQAAAAAAAAKBAAACAQAAAAAA=","byteLength":284}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":72,"byteLength":168},{"buffer":0,"byteOffset":240,"byteLength":6},{"buffer":0,"byteOffset":248,"byteLength":36}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5123,"count":36,"type":"SCALAR","max":[13],"min":[0]},{"bufferView":1,"byteOffset":0,"componentType":5126,"count":14,"type":"VEC3","max":[6,4,0],"min":[0,0,0],"sparse":{"count":3,"indices":{"bufferView":2,"byteOffset":0,"componentType":5123},"values":{"bufferView":3,"byteOffset":0}}}],"asset":{"version":"2.0"}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"POSITION":1},"indices":0}]}],"buffers":[{"uri":"data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAA=","byteLength":80}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":6,"target":34963},{"buffer":0,"byteOffset":8,"byteLength":72,"byteStride":24,"target":34962}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5123,"count":3,"type":"SCALAR","max":[2],"min":[0]},{"bufferView":1,"byteOffset":0,"componentType":5126,"count":3,"type":"VEC3","max":[1,1,0],"min":[0,0,0]}],"asset":{"version":"2.0"}}

View file

@ -0,0 +1 @@
{"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"POSITION":0}}]}],"buffers":[{"uri":"data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA","byteLength":36}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":36,"target":34962}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5126,"count":3,"type":"VEC3","max":[1,1,0],"min":[0,0,0]}],"asset":{"version":"2.0"}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -208,9 +208,75 @@ minetest.register_chatcommand("zoomfov", {
end,
})
-- Hotbars
local hud_hotbar_defs = {
{
type = "hotbar",
position = {x=0.2, y=0.5},
direction = 0,
alignment = {x=1, y=-1},
},
{
type = "hotbar",
position = {x=0.2, y=0.5},
direction = 2,
alignment = {x=1, y=1},
},
{
type = "hotbar",
position = {x=0.7, y=0.5},
direction = 0,
offset = {x=140, y=20},
alignment = {x=-1, y=-1},
},
{
type = "hotbar",
position = {x=0.7, y=0.5},
direction = 2,
offset = {x=140, y=20},
alignment = {x=-1, y=1},
},
}
local player_hud_hotbars= {}
minetest.register_chatcommand("hudhotbars", {
description = "Shows some test Lua HUD elements of type hotbar. " ..
"(add: Adds elements (default). remove: Removes elements)",
params = "[ add | remove ]",
func = function(name, params)
local player = minetest.get_player_by_name(name)
if not player then
return false, "No player."
end
local id_table = player_hud_hotbars[name]
if not id_table then
id_table = {}
player_hud_hotbars[name] = id_table
end
if params == "remove" then
for _, id in ipairs(id_table) do
player:hud_remove(id)
end
return true, "Hotbars removed."
end
-- params == "add" or default
for _, def in ipairs(hud_hotbar_defs) do
table.insert(id_table, player:hud_add(def))
end
return true, #hud_hotbar_defs .." Hotbars added."
end
})
minetest.register_on_leaveplayer(function(player)
player_font_huds[player:get_player_name()] = nil
player_waypoints[player:get_player_name()] = nil
player_hud_hotbars[player:get_player_name()] = nil
end)
minetest.register_chatcommand("hudprint", {
@ -232,3 +298,26 @@ minetest.register_chatcommand("hudprint", {
return true, s
end
})
local hud_flags = {"hotbar", "healthbar", "crosshair", "wielditem", "breathbar",
"minimap", "minimap_radar", "basic_debug", "chat"}
minetest.register_chatcommand("hudtoggleflag", {
description = "Toggles a hud flag.",
params = "[ ".. table.concat(hud_flags, " | ") .." ]",
func = function(name, params)
local player = minetest.get_player_by_name(name)
if not player then
return false, "No player."
end
local flags = player:hud_get_flags()
if flags[params] == nil then
return false, "Unknown hud flag."
end
flags[params] = not flags[params]
player:hud_set_flags(flags)
return true, "Flag \"".. params .."\" set to ".. tostring(flags[params]) .. "."
end
})

View file

@ -214,3 +214,23 @@ unittests.register("test_objects_in_area", function(_, pos)
return core.objects_in_area(pos:offset(-1, -1, -1), pos:offset(1, 1, 1))
end)
end, {map=true})
-- Tests that bone rotation euler angles are preserved (see #14992)
local function test_get_bone_rot(_, pos)
local obj = core.add_entity(pos, "unittests:dummy")
for _ = 1, 100 do
local function assert_similar(euler_angles)
local _, rot = obj:get_bone_position("bonename")
assert(euler_angles:distance(rot) < 1e-3)
local override = obj:get_bone_override("bonename")
assert(euler_angles:distance(override.rotation.vec:apply(math.deg)) < 1e-3)
end
local deg = 1e3 * vector.new(math.random(), math.random(), math.random())
obj:set_bone_position("bonename", vector.zero(), deg)
assert_similar(deg)
local rad = 3 * math.pi * vector.new(math.random(), math.random(), math.random())
obj:set_bone_override("bonename", {rotation = {vec = rad}})
assert_similar(rad:apply(math.deg))
end
end
unittests.register("test_get_bone_rot", test_get_bone_rot, {map=true})

View file

@ -2,7 +2,7 @@
-- HP Change Reasons
--
local expect = nil
minetest.register_on_player_hpchange(function(player, hp, reason)
core.register_on_player_hpchange(function(player, hp_change, reason)
if expect == nil then
return
end
@ -37,6 +37,48 @@ local function run_hpchangereason_tests(player)
end
unittests.register("test_hpchangereason", run_hpchangereason_tests, {player=true})
--
-- HP differences
--
local expected_diff = nil
core.register_on_player_hpchange(function(player, hp_change, reason)
if expected_diff then
assert(hp_change == expected_diff)
end
end)
local function run_hp_difference_tests(player)
local old_hp = player:get_hp()
local old_hp_max = player:get_properties().hp_max
expected_diff = nil
player:set_properties({hp_max = 30})
player:set_hp(22)
-- final HP value is clamped to >= 0 before difference calculation
expected_diff = -22
player:set_hp(-3)
-- and actual final HP value is clamped to >= 0 too
assert(player:get_hp() == 0)
expected_diff = 22
player:set_hp(22)
assert(player:get_hp() == 22)
-- final HP value is clamped to <= U16_MAX before difference calculation
expected_diff = 65535 - 22
player:set_hp(1000000)
-- and actual final HP value is clamped to <= hp_max
assert(player:get_hp() == 30)
expected_diff = nil
player:set_properties({hp_max = old_hp_max})
player:set_hp(old_hp)
core.close_formspec(player:get_player_name(), "") -- hide death screen
end
unittests.register("test_hp_difference", run_hp_difference_tests, {player=true})
--
-- Player meta
--

View file

@ -1,310 +0,0 @@
name: build
# build on c/cpp changes or workflow changes
on:
- push
- pull_request
jobs:
linux-gl:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
sudo apt-get update
sudo apt-get install g++ cmake libxi-dev libgl1-mesa-dev libpng-dev libjpeg-dev zlib1g-dev -qyy
- name: Build
run: |
cmake . -DUSE_SDL2=OFF
make VERBOSE=1 -j2
- name: Test
run: |
ctest --output-on-failure
- name: Package
run: |
make DESTDIR=$PWD/_install install
tar -c -I "gzip -9" -f irrlicht-linux.tar.gz -C ./_install/usr/local .
- uses: actions/upload-artifact@v4
with:
name: irrlicht-linux
path: ./irrlicht-linux.tar.gz
linux-gles:
# Xvfb test is broken on 20.04 for unknown reasons (not our bug)
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
sudo apt-get update
sudo apt-get install g++ cmake libxi-dev libgles2-mesa-dev libpng-dev libjpeg-dev zlib1g-dev xvfb -qyy
- name: Build
run: |
cmake . -DBUILD_EXAMPLES=1 -DUSE_SDL2=OFF -DENABLE_OPENGL=OFF -DENABLE_GLES2=ON
make -j2
- name: Test (headless)
run: |
cd bin/Linux
./AutomatedTest null
- name: Test (Xvfb)
run: |
cd bin/Linux
LIBGL_ALWAYS_SOFTWARE=true xvfb-run ./AutomatedTest ogles2
linux-sdl:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
sudo apt-get update
sudo apt-get install g++ cmake libsdl2-dev libpng-dev libjpeg-dev zlib1g-dev -qyy
- name: Build
run: |
cmake . -DBUILD_EXAMPLES=1 -DUSE_SDL2=ON -DCMAKE_BUILD_TYPE=Debug
make -j2
- name: Test (headless)
run: |
cd bin/Linux
./AutomatedTest null
linux-sdl-gl3:
# Xvfb test is broken on 20.04 for unknown reasons (not our bug)
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
sudo apt-get update
sudo apt-get install g++ cmake libsdl2-dev libpng-dev libjpeg-dev zlib1g-dev xvfb -qyy
- name: Build
run: |
cmake . -DBUILD_EXAMPLES=1 -DUSE_SDL2=ON -DENABLE_OPENGL=OFF -DENABLE_OPENGL3=ON
make -j2
- name: Test (headless)
run: |
cd bin/Linux
./AutomatedTest null
- name: Test (Xvfb)
run: |
cd bin/Linux
LIBGL_ALWAYS_SOFTWARE=true xvfb-run ./AutomatedTest opengl3
linux-sdl-gles2:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
sudo apt-get update
sudo apt-get install g++ cmake libsdl2-dev libpng-dev libjpeg-dev zlib1g-dev xvfb -qyy
- name: Build
run: |
cmake . -DBUILD_EXAMPLES=1 -DUSE_SDL2=ON -DENABLE_OPENGL=OFF -DENABLE_GLES2=ON
make -j2
- name: Test (headless)
run: |
cd bin/Linux
./AutomatedTest null
- name: Test (Xvfb)
run: |
cd bin/Linux
LIBGL_ALWAYS_SOFTWARE=true xvfb-run ./AutomatedTest ogles2
mingw:
name: "MinGW ${{matrix.config.variant}}${{matrix.config.extras}}"
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
config:
- {variant: win32, arch: i686}
- {variant: win64, arch: x86_64}
- {variant: win32, arch: i686, extras: "-sdl"}
- {variant: win64, arch: x86_64, extras: "-sdl"}
steps:
- uses: actions/checkout@v4
- name: Install compiler
run: |
sudo apt-get update && sudo apt-get install cmake -qyy
./scripts/ci-get-mingw.sh
- name: Build
run: |
./scripts/ci-build-mingw.sh package
env:
CC: ${{matrix.config.arch}}-w64-mingw32-clang
CXX: ${{matrix.config.arch}}-w64-mingw32-clang++
extras: ${{matrix.config.extras}}
- uses: actions/upload-artifact@v4
with:
name: irrlicht-${{matrix.config.variant}}${{matrix.config.extras}}
path: ./irrlicht-${{matrix.config.variant}}${{matrix.config.extras}}.zip
macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
brew update --auto-update
brew install cmake libpng jpeg
env:
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
HOMEBREW_NO_INSTALL_CLEANUP: 1
- name: Build
run: |
cmake . -DCMAKE_FIND_FRAMEWORK=LAST -DBUILD_EXAMPLES=1
make -j3
- name: Test (headless)
run: |
./bin/OSX/AutomatedTest null
macos-sdl:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
brew update --auto-update
brew install cmake libpng jpeg sdl2
env:
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
HOMEBREW_NO_INSTALL_CLEANUP: 1
- name: Build
run: |
cmake . -DCMAKE_FIND_FRAMEWORK=LAST -DBUILD_EXAMPLES=1 -DUSE_SDL2=1
make -j3
msvc:
name: VS 2019 ${{ matrix.config.arch }} ${{ matrix.sdl.label }}
runs-on: windows-2019
env:
VCPKG_VERSION: 8eb57355a4ffb410a2e94c07b4dca2dffbee8e50
# 2023.10.19
vcpkg_packages: zlib libpng libjpeg-turbo
strategy:
fail-fast: false
matrix:
config:
-
arch: x86
generator: "-G'Visual Studio 16 2019' -A Win32"
vcpkg_triplet: x86-windows
-
arch: x64
generator: "-G'Visual Studio 16 2019' -A x64"
vcpkg_triplet: x64-windows
sdl:
-
use: FALSE
label: '(no SDL)'
vcpkg_packages: opengl-registry
-
use: TRUE
label: '(with SDL)'
vcpkg_packages: sdl2
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Restore from cache and run vcpkg
uses: lukka/run-vcpkg@v7
with:
vcpkgArguments: ${{env.vcpkg_packages}} ${{matrix.sdl.vcpkg_packages}}
vcpkgDirectory: '${{ github.workspace }}\vcpkg'
appendedCacheKey: ${{ matrix.config.vcpkg_triplet }}
vcpkgGitCommitId: ${{ env.VCPKG_VERSION }}
vcpkgTriplet: ${{ matrix.config.vcpkg_triplet }}
- name: CMake
run: |
cmake ${{matrix.config.generator}} `
-DUSE_SDL2=${{matrix.sdl.use}} `
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}\vcpkg\scripts\buildsystems\vcpkg.cmake" `
-DCMAKE_BUILD_TYPE=Release .
- name: Build
run: cmake --build . --config Release
- name: Create artifact folder
run: |
mkdir artifact/
mkdir artifact/lib/
- name: Move dlls into artifact folder
run: move bin\Win32-VisualStudio\Release\* artifact\lib\
- name: Move includes into artifact folder
run: move include artifact/
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: msvc-${{ matrix.config.arch }}-${{matrix.sdl.use}}
path: artifact/
android:
name: Android ${{ matrix.arch }}
runs-on: ubuntu-20.04
env:
ndk_version: "r25c"
ANDROID_NDK: ${{ github.workspace }}/android-ndk
strategy:
matrix:
arch: [armeabi-v7a, arm64-v8a, x86, x86_64]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install deps
run: |
sudo rm /var/lib/man-db/auto-update
sudo apt-get update
sudo apt-get install -qyy wget unzip zip gcc-multilib make cmake
- name: Cache NDK
id: cache-ndk
uses: actions/cache@v4
with:
key: android-ndk-${{ env.ndk_version }}-linux
path: ${{ env.ANDROID_NDK }}
- name: Install NDK
run: |
wget --progress=bar:force "http://dl.google.com/android/repository/android-ndk-${ndk_version}-linux.zip"
unzip -q "android-ndk-${ndk_version}-linux.zip"
rm "android-ndk-${ndk_version}-linux.zip"
mv "android-ndk-${ndk_version}" "${ANDROID_NDK}"
if: ${{ steps.cache-ndk.outputs.cache-hit != 'true' }}
- name: Build
run: ./scripts/ci-build-android.sh ${{ matrix.arch }}
#- name: Upload Artifact
# uses: actions/upload-artifact@v4
# with:
# name: irrlicht-android-${{ matrix.arch }}
# path: ${{ runner.temp }}/pkg/${{ matrix.arch }}

View file

@ -11,14 +11,5 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type: Debug or Release" FORCE)
endif()
# FIXME: tests need to be moved to MT if we want to keep them
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
#enable_testing()
add_subdirectory(src)
#add_subdirectory(test)
#option(BUILD_EXAMPLES "Build example applications" FALSE)
#if(BUILD_EXAMPLES)
# add_subdirectory(examples)
#endif()

View file

@ -20,12 +20,11 @@ The following libraries are required to be installed:
Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the following options are available:
* `ENABLE_OPENGL` - Enable OpenGL driver
* `ENABLE_OPENGL3` (default: `OFF`) - Enable OpenGL 3+ driver
* `ENABLE_GLES1` - Enable OpenGL ES driver, legacy
* `ENABLE_GLES2` - Enable OpenGL ES 2+ driver
* `USE_SDL2` (default: platform-dependent, usually `ON`) - Use SDL2 instead of older native device code
However, IrrlichtMt cannot be built or installed separately.
Platforms
---------

View file

@ -1,154 +0,0 @@
#include <iostream>
#include <irrlicht.h>
#include "exampleHelper.h"
using namespace irr;
static IrrlichtDevice *device = nullptr;
static int test_fail = 0;
void test_irr_array();
void test_irr_string();
static video::E_DRIVER_TYPE chooseDriver(core::stringc arg_)
{
if (arg_ == "null")
return video::EDT_NULL;
if (arg_ == "ogles1")
return video::EDT_OGLES1;
if (arg_ == "ogles2")
return video::EDT_OGLES2;
if (arg_ == "opengl")
return video::EDT_OPENGL;
if (arg_ == "opengl3")
return video::EDT_OPENGL3;
std::cerr << "Unknown driver type: " << arg_.c_str() << ". Trying OpenGL." << std::endl;
return video::EDT_OPENGL;
}
static inline void check(bool ok, const char *msg)
{
if (!ok) {
test_fail++;
device->getLogger()->log((core::stringc("FAILED TEST: ") + msg).c_str(), ELL_ERROR);
}
}
void run_unit_tests()
{
std::cout << "Running unit tests:" << std::endl;
try {
test_irr_array();
test_irr_string();
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
test_fail++;
}
std::cout << std::endl;
}
int main(int argc, char *argv[])
{
run_unit_tests();
SIrrlichtCreationParameters p;
p.DriverType = chooseDriver(argc > 1 ? argv[1] : "");
p.WindowSize = core::dimension2du(640, 480);
p.Vsync = true;
p.LoggingLevel = ELL_DEBUG;
device = createDeviceEx(p);
if (!device)
return 1;
{
u32 total = 0;
device->getOSOperator()->getSystemMemory(&total, nullptr);
core::stringc message = core::stringc("Total RAM in MiB: ") + core::stringc(total >> 10);
device->getLogger()->log(message.c_str(), ELL_INFORMATION);
check(total > 130 * 1024, "RAM amount");
}
device->setWindowCaption(L"Hello World!");
device->setResizable(true);
video::IVideoDriver *driver = device->getVideoDriver();
scene::ISceneManager *smgr = device->getSceneManager();
gui::IGUIEnvironment *guienv = device->getGUIEnvironment();
guienv->addStaticText(L"sample text", core::rect<s32>(10, 10, 110, 22), false);
gui::IGUIButton *button = guienv->addButton(
core::rect<s32>(10, 30, 110, 30 + 32), 0, -1, L"sample button",
L"sample tooltip");
gui::IGUIEditBox *editbox = guienv->addEditBox(L"",
core::rect<s32>(10, 70, 60, 70 + 16));
const io::path mediaPath = getExampleMediaPath();
auto mesh_file = device->getFileSystem()->createAndOpenFile(mediaPath + "coolguy_opt.x");
check(mesh_file, "mesh file loading");
scene::IAnimatedMesh *mesh = smgr->getMesh(mesh_file);
check(mesh, "mesh loading");
if (mesh_file)
mesh_file->drop();
if (mesh) {
video::ITexture *tex = driver->getTexture(mediaPath + "cooltexture.png");
check(tex, "texture loading");
scene::IAnimatedMeshSceneNode *node = smgr->addAnimatedMeshSceneNode(mesh);
if (node) {
node->forEachMaterial([tex](video::SMaterial &mat) {
mat.Lighting = false;
mat.setTexture(0, tex);
});
node->setFrameLoop(0, 29);
node->setAnimationSpeed(30);
}
}
smgr->addCameraSceneNode(0, core::vector3df(0, 4, 5), core::vector3df(0, 2, 0));
s32 n = 0;
SEvent event;
device->getTimer()->start();
while (device->run()) {
if (device->getTimer()->getTime() >= 1000) {
device->getTimer()->setTime(0);
++n;
if (n == 1) { // Tooltip display
bzero(&event, sizeof(SEvent));
event.EventType = irr::EET_MOUSE_INPUT_EVENT;
event.MouseInput.Event = irr::EMIE_MOUSE_MOVED;
event.MouseInput.X = button->getAbsolutePosition().getCenter().X;
event.MouseInput.Y = button->getAbsolutePosition().getCenter().Y;
device->postEventFromUser(event);
} else if (n == 2) // Text input focus
guienv->setFocus(editbox);
else if (n == 3) { // Keypress for Text input
bzero(&event, sizeof(SEvent));
event.EventType = irr::EET_KEY_INPUT_EVENT;
event.KeyInput.Char = L'a';
event.KeyInput.Key = KEY_KEY_A;
event.KeyInput.PressedDown = true;
device->postEventFromUser(event);
event.KeyInput.PressedDown = false;
device->postEventFromUser(event);
} else
device->closeDevice();
}
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH,
video::SColor(255, 100, 100, 150));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
check(core::stringw(L"a") == editbox->getText(), "EditBox text");
device->getLogger()->log("Done.", ELL_INFORMATION);
device->drop();
return test_fail > 0 ? 1 : 0;
}

View file

@ -1,138 +0,0 @@
#include <irrArray.h>
#include "test_helper.h"
using namespace irr;
using core::array;
static void test_basics()
{
array<int> v;
v.push_back(1); // 1
v.push_front(2); // 2, 1
v.insert(4, 0); // 4, 2, 1
v.insert(3, 1); // 4, 3, 2, 1
v.insert(0, 4); // 4, 3, 2, 1, 0
UASSERTEQ(v.size(), 5);
UASSERTEQ(v[0], 4);
UASSERTEQ(v[1], 3);
UASSERTEQ(v[2], 2);
UASSERTEQ(v[3], 1);
UASSERTEQ(v[4], 0);
array<int> w = v;
UASSERTEQ(w.size(), 5);
UASSERT(w == v);
w.clear();
UASSERTEQ(w.size(), 0);
UASSERTEQ(w.allocated_size(), 0);
UASSERT(w.empty());
w = v;
UASSERTEQ(w.size(), 5);
w.set_used(3);
UASSERTEQ(w.size(), 3);
UASSERTEQ(w[0], 4);
UASSERTEQ(w[1], 3);
UASSERTEQ(w[2], 2);
UASSERTEQ(w.getLast(), 2);
w.set_used(20);
UASSERTEQ(w.size(), 20);
w = v;
w.sort();
UASSERTEQ(w.size(), 5);
UASSERTEQ(w[0], 0);
UASSERTEQ(w[1], 1);
UASSERTEQ(w[2], 2);
UASSERTEQ(w[3], 3);
UASSERTEQ(w[4], 4);
w.erase(0);
UASSERTEQ(w.size(), 4);
UASSERTEQ(w[0], 1);
UASSERTEQ(w[1], 2);
UASSERTEQ(w[2], 3);
UASSERTEQ(w[3], 4);
w.erase(1, 2);
UASSERTEQ(w.size(), 2);
UASSERTEQ(w[0], 1);
UASSERTEQ(w[1], 4);
w.swap(v);
UASSERTEQ(w.size(), 5);
UASSERTEQ(v.size(), 2);
}
static void test_linear_searches()
{
// Populate the array with 0, 1, 2, ..., 100, 100, 99, 98, 97, ..., 0
array<int> arr;
for (int i = 0; i <= 100; i++)
arr.push_back(i);
for (int i = 100; i >= 0; i--)
arr.push_back(i);
s32 end = arr.size() - 1;
for (int i = 0; i <= 100; i++) {
s32 index = arr.linear_reverse_search(i);
UASSERTEQ(index, end - i);
}
for (int i = 0; i <= 100; i++) {
s32 index = arr.linear_search(i);
UASSERTEQ(index, i);
}
}
static void test_binary_searches()
{
const auto &values = {3, 5, 1, 2, 5, 10, 19, 9, 7, 1, 2, 5, 8, 15};
array<int> arr;
for (int value : values) {
arr.push_back(value);
}
// Test the const form first, it uses a linear search without sorting
const array<int> &carr = arr;
UASSERTEQ(carr.binary_search(20), -1);
UASSERTEQ(carr.binary_search(0), -1);
UASSERTEQ(carr.binary_search(1), 2);
// Sorted: 1, 1, 2, 2, 3, 5, 5, 5, 7, 8, 9, 10, 15, 19
UASSERTEQ(arr.binary_search(20), -1);
UASSERTEQ(arr.binary_search(0), -1);
for (int value : values) {
s32 i = arr.binary_search(value);
UASSERTNE(i, -1);
UASSERTEQ(arr[i], value);
}
s32 first, last;
first = arr.binary_search_multi(1, last);
UASSERTEQ(first, 0);
UASSERTEQ(last, 1);
first = arr.binary_search_multi(2, last);
UASSERTEQ(first, 2);
UASSERTEQ(last, 3);
first = arr.binary_search_multi(3, last);
UASSERTEQ(first, 4);
UASSERTEQ(last, 4);
first = arr.binary_search_multi(4, last);
UASSERTEQ(first, -1);
first = arr.binary_search_multi(5, last);
UASSERTEQ(first, 5);
UASSERTEQ(last, 7);
first = arr.binary_search_multi(7, last);
UASSERTEQ(first, 8);
UASSERTEQ(last, 8);
first = arr.binary_search_multi(19, last);
UASSERTEQ(first, 13);
UASSERTEQ(last, 13);
}
void test_irr_array()
{
test_basics();
test_linear_searches();
test_binary_searches();
std::cout << " test_irr_array PASSED" << std::endl;
}

View file

@ -1,33 +0,0 @@
#pragma once
#include <exception>
#include <iostream>
class TestFailedException : public std::exception
{
};
// Asserts the comparison specified by CMP is true, or fails the current unit test
#define UASSERTCMP(CMP, actual, expected) \
do { \
const auto &a = (actual); \
const auto &e = (expected); \
if (!CMP(a, e)) { \
std::cout \
<< "Test assertion failed: " << #actual << " " << #CMP << " " \
<< #expected << std::endl \
<< " at " << __FILE__ << ":" << __LINE__ << std::endl \
<< " actual: " << a << std::endl \
<< " expected: " \
<< e << std::endl; \
throw TestFailedException(); \
} \
} while (0)
#define CMPEQ(a, e) (a == e)
#define CMPTRUE(a, e) (a)
#define CMPNE(a, e) (a != e)
#define UASSERTEQ(actual, expected) UASSERTCMP(CMPEQ, actual, expected)
#define UASSERTNE(actual, nexpected) UASSERTCMP(CMPNE, actual, nexpected)
#define UASSERT(actual) UASSERTCMP(CMPTRUE, actual, true)

View file

@ -1,205 +0,0 @@
#include <irrString.h>
#include <cstring>
#include <clocale>
#include <vector>
#include "test_helper.h"
using namespace irr;
using namespace irr::core;
#define CMPSTR(a, b) (!strcmp(a, b))
#define UASSERTSTR(actual, expected) UASSERTCMP(CMPSTR, actual.c_str(), expected)
static void test_basics()
{
// ctor
stringc s;
UASSERTEQ(s.c_str()[0], '\0');
s = stringc(0.1234567);
UASSERTSTR(s, "0.123457");
s = stringc(0x1p+53);
UASSERTSTR(s, "9007199254740992.000000");
s = stringc(static_cast<int>(-102400));
UASSERTSTR(s, "-102400");
s = stringc(static_cast<unsigned int>(102400));
UASSERTSTR(s, "102400");
s = stringc(static_cast<long>(-1024000));
UASSERTSTR(s, "-1024000");
s = stringc(static_cast<unsigned long>(1024000));
UASSERTSTR(s, "1024000");
s = stringc("YESno", 3);
UASSERTSTR(s, "YES");
s = stringc(L"test", 4);
UASSERTSTR(s, "test");
s = stringc("Hello World!");
UASSERTSTR(s, "Hello World!");
// operator=
s = stringw(L"abcdef");
UASSERTSTR(s, "abcdef");
s = L"abcdef";
UASSERTSTR(s, "abcdef");
s = static_cast<const char *>(nullptr);
UASSERTSTR(s, "");
// operator+
s = s + stringc("foo");
UASSERTSTR(s, "foo");
s = s + L"bar";
UASSERTSTR(s, "foobar");
// the rest
s = "f";
UASSERTEQ(s[0], 'f');
const auto &sref = s;
UASSERTEQ(sref[0], 'f');
UASSERT(sref == "f");
UASSERT(sref == stringc("f"));
s = "a";
UASSERT(sref < stringc("aa"));
UASSERT(sref < stringc("b"));
UASSERT(stringc("Z") < sref);
UASSERT(!(sref < stringc("a")));
UASSERT(sref.lower_ignore_case("AA"));
UASSERT(sref.lower_ignore_case("B"));
UASSERT(!sref.lower_ignore_case("A"));
s = "dog";
UASSERT(sref != "cat");
UASSERT(sref != stringc("cat"));
}
static void test_methods()
{
stringc s;
const auto &sref = s;
s = "irrlicht";
UASSERTEQ(sref.size(), 8);
UASSERT(!sref.empty());
s.clear();
UASSERTEQ(sref.size(), 0);
UASSERT(sref.empty());
UASSERT(sref[0] == 0);
s = "\tAz#`";
s.make_lower();
UASSERTSTR(s, "\taz#`");
s.make_upper();
UASSERTSTR(s, "\tAZ#`");
UASSERT(sref.equals_ignore_case("\taz#`"));
UASSERT(sref.equals_substring_ignore_case("Z#`", 2));
s = "irrlicht";
UASSERT(sref.equalsn(stringc("irr"), 3));
UASSERT(sref.equalsn("irr", 3));
s = "fo";
s.append('o');
UASSERTSTR(s, "foo");
s.append("bar", 1);
UASSERTSTR(s, "foob");
s.append("ar", 999999);
UASSERTSTR(s, "foobar");
s = "nyan";
s.append(stringc("cat"));
UASSERTSTR(s, "nyancat");
s.append(stringc("sam"), 1);
UASSERTSTR(s, "nyancats");
s = "fbar";
s.insert(1, "ooXX", 2);
UASSERTSTR(s, "foobar");
UASSERTEQ(sref.findFirst('o'), 1);
UASSERTEQ(sref.findFirst('X'), -1);
UASSERTEQ(sref.findFirstChar("abff", 2), 3);
UASSERTEQ(sref.findFirstCharNotInList("fobb", 2), 3);
UASSERTEQ(sref.findLast('o'), 2);
UASSERTEQ(sref.findLast('X'), -1);
UASSERTEQ(sref.findLastChar("abrr", 2), 4);
UASSERTEQ(sref.findLastCharNotInList("rabb", 2), 3);
UASSERTEQ(sref.findNext('o', 2), 2);
UASSERTEQ(sref.findLast('o', 1), 1);
s = "ob-oob";
UASSERTEQ(sref.find("ob", 1), 4);
UASSERTEQ(sref.find("ob"), 0);
UASSERTEQ(sref.find("?"), -1);
s = "HOMEOWNER";
stringc s2 = sref.subString(2, 4);
UASSERTSTR(s2, "MEOW");
s2 = sref.subString(2, 4, true);
UASSERTSTR(s2, "meow");
s = "land";
s.replace('l', 's');
UASSERTSTR(s, "sand");
s = ">dog<";
s.replace("dog", "cat");
UASSERTSTR(s, ">cat<");
s.replace("cat", "horse");
UASSERTSTR(s, ">horse<");
s.replace("horse", "gnu");
UASSERTSTR(s, ">gnu<");
s = " h e l p ";
s.remove(' ');
UASSERTSTR(s, "help");
s.remove("el");
UASSERTSTR(s, "hp");
s = "irrlicht";
s.removeChars("it");
UASSERTSTR(s, "rrlch");
s = "\r\nfoo bar ";
s.trim();
UASSERTSTR(s, "foo bar");
s = "foxo";
s.erase(2);
UASSERTSTR(s, "foo");
s = "a";
s.append('\0');
s.append('b');
UASSERTEQ(s.size(), 3);
s.validate();
UASSERTEQ(s.size(), 1);
UASSERTEQ(s.lastChar(), 'a');
std::vector<stringc> res;
s = "a,,b,c";
s.split(res, ",aa", 1, true, false);
UASSERTEQ(res.size(), 3);
UASSERTSTR(res[0], "a");
UASSERTSTR(res[2], "c");
res.clear();
s.split(res, ",", 1, false, true);
UASSERTEQ(res.size(), 7);
UASSERTSTR(res[0], "a");
UASSERTSTR(res[2], "");
for (int i = 0; i < 3; i++)
UASSERTSTR(res[2 * i + 1], ",");
}
static void test_conv()
{
// locale-independent
stringw out;
utf8ToWString(out, "†††");
UASSERTEQ(out.size(), 3);
for (int i = 0; i < 3; i++)
UASSERTEQ(static_cast<u16>(out[i]), 0x2020);
stringc out2;
wStringToUTF8(out2, L"†††");
UASSERTEQ(out2.size(), 9);
for (int i = 0; i < 3; i++) {
UASSERTEQ(static_cast<u8>(out2[3 * i]), 0xe2);
UASSERTEQ(static_cast<u8>(out2[3 * i + 1]), 0x80);
UASSERTEQ(static_cast<u8>(out2[3 * i + 2]), 0xa0);
}
// locale-dependent
if (!setlocale(LC_CTYPE, "C.UTF-8"))
setlocale(LC_CTYPE, "UTF-8"); // macOS
stringw out3;
multibyteToWString(out3, "†††");
UASSERTEQ(out3.size(), 3);
for (int i = 0; i < 3; i++)
UASSERTEQ(static_cast<u16>(out3[i]), 0x2020);
}
void test_irr_string()
{
test_basics();
test_methods();
test_conv();
std::cout << " test_irr_string PASSED" << std::endl;
}

View file

@ -1,17 +0,0 @@
set(IRREXAMPLES
# removed
)
if(UNIX)
list(APPEND IRREXAMPLES AutomatedTest)
endif()
foreach(exname IN ITEMS ${IRREXAMPLES})
file(GLOB sources "${CMAKE_CURRENT_SOURCE_DIR}/${exname}/*.cpp")
add_executable(${exname} ${sources})
target_include_directories(${exname} PRIVATE
${CMAKE_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/${exname}
)
target_link_libraries(${exname} IrrlichtMt)
endforeach()

View file

@ -0,0 +1,89 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include <vector>
#include "IIndexBuffer.h"
namespace irr
{
namespace scene
{
//! Template implementation of the IIndexBuffer interface
template <class T>
class CIndexBuffer final : public IIndexBuffer
{
public:
//! Default constructor for empty buffer
CIndexBuffer()
{
#ifdef _DEBUG
setDebugName("CIndexBuffer");
#endif
}
video::E_INDEX_TYPE getType() const override
{
static_assert(sizeof(T) == 2 || sizeof(T) == 4, "invalid index type");
return sizeof(T) == 2 ? video::EIT_16BIT : video::EIT_32BIT;
}
const void *getData() const override
{
return Data.data();
}
void *getData() override
{
return Data.data();
}
u32 getCount() const override
{
return static_cast<u32>(Data.size());
}
E_HARDWARE_MAPPING getHardwareMappingHint() const override
{
return MappingHint;
}
void setHardwareMappingHint(E_HARDWARE_MAPPING NewMappingHint) override
{
MappingHint = NewMappingHint;
}
void setDirty() override
{
++ChangedID;
}
u32 getChangedID() const override { return ChangedID; }
void setHWBuffer(void *ptr) const override
{
HWBuffer = ptr;
}
void *getHWBuffer() const override
{
return HWBuffer;
}
u32 ChangedID = 1;
//! hardware mapping hint
E_HARDWARE_MAPPING MappingHint = EHM_NEVER;
mutable void *HWBuffer = nullptr;
//! Indices of this buffer
std::vector<T> Data;
};
//! Standard 16-bit buffer
typedef CIndexBuffer<u16> SIndexBuffer;
} // end namespace scene
} // end namespace irr

View file

@ -4,8 +4,10 @@
#pragma once
#include "irrArray.h"
#include <vector>
#include "IMeshBuffer.h"
#include "CVertexBuffer.h"
#include "CIndexBuffer.h"
namespace irr
{
@ -13,16 +15,24 @@ namespace scene
{
//! Template implementation of the IMeshBuffer interface
template <class T>
class CMeshBuffer : public IMeshBuffer
class CMeshBuffer final : public IMeshBuffer
{
public:
//! Default constructor for empty meshbuffer
CMeshBuffer() :
ChangedID_Vertex(1), ChangedID_Index(1), MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER), HWBuffer(NULL), PrimitiveType(EPT_TRIANGLES)
PrimitiveType(EPT_TRIANGLES)
{
#ifdef _DEBUG
setDebugName("CMeshBuffer");
#endif
Vertices = new CVertexBuffer<T>();
Indices = new SIndexBuffer();
}
~CMeshBuffer()
{
Vertices->drop();
Indices->drop();
}
//! Get material of this meshbuffer
@ -39,53 +49,24 @@ public:
return Material;
}
//! Get pointer to vertices
/** \return Pointer to vertices. */
const void *getVertices() const override
const scene::IVertexBuffer *getVertexBuffer() const override
{
return Vertices.const_pointer();
return Vertices;
}
//! Get pointer to vertices
/** \return Pointer to vertices. */
void *getVertices() override
scene::IVertexBuffer *getVertexBuffer() override
{
return Vertices.pointer();
return Vertices;
}
//! Get number of vertices
/** \return Number of vertices. */
u32 getVertexCount() const override
const scene::IIndexBuffer *getIndexBuffer() const override
{
return Vertices.size();
return Indices;
}
//! Get type of index data which is stored in this meshbuffer.
/** \return Index type of this buffer. */
video::E_INDEX_TYPE getIndexType() const override
scene::IIndexBuffer *getIndexBuffer() override
{
return video::EIT_16BIT;
}
//! Get pointer to indices
/** \return Pointer to indices. */
const u16 *getIndices() const override
{
return Indices.const_pointer();
}
//! Get pointer to indices
/** \return Pointer to indices. */
u16 *getIndices() override
{
return Indices.pointer();
}
//! Get number of indices
/** \return Number of indices. */
u32 getIndexCount() const override
{
return Indices.size();
return Indices;
}
//! Get the axis aligned bounding box
@ -107,102 +88,34 @@ public:
/** should be called if the mesh changed. */
void recalculateBoundingBox() override
{
if (!Vertices.empty()) {
BoundingBox.reset(Vertices[0].Pos);
const irr::u32 vsize = Vertices.size();
if (Vertices->getCount()) {
BoundingBox.reset(Vertices->getPosition(0));
const irr::u32 vsize = Vertices->getCount();
for (u32 i = 1; i < vsize; ++i)
BoundingBox.addInternalPoint(Vertices[i].Pos);
BoundingBox.addInternalPoint(Vertices->getPosition(i));
} else
BoundingBox.reset(0, 0, 0);
}
//! Get type of vertex data stored in this buffer.
/** \return Type of vertex data. */
video::E_VERTEX_TYPE getVertexType() const override
{
return T::getType();
}
//! returns position of vertex i
const core::vector3df &getPosition(u32 i) const override
{
return Vertices[i].Pos;
}
//! returns position of vertex i
core::vector3df &getPosition(u32 i) override
{
return Vertices[i].Pos;
}
//! returns normal of vertex i
const core::vector3df &getNormal(u32 i) const override
{
return Vertices[i].Normal;
}
//! returns normal of vertex i
core::vector3df &getNormal(u32 i) override
{
return Vertices[i].Normal;
}
//! returns texture coord of vertex i
const core::vector2df &getTCoords(u32 i) const override
{
return Vertices[i].TCoords;
}
//! returns texture coord of vertex i
core::vector2df &getTCoords(u32 i) override
{
return Vertices[i].TCoords;
}
//! Append the vertices and indices to the current buffer
/** Only works for compatible types, i.e. either the same type
or the main buffer is of standard type. Otherwise, behavior is
undefined.
*/
void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) override
{
if (vertices == getVertices())
return;
const u32 vertexCount = getVertexCount();
u32 i;
const u32 indexCount = getIndexCount();
Vertices.reallocate(vertexCount + numVertices);
for (i = 0; i < numVertices; ++i) {
Vertices.push_back(static_cast<const T *>(vertices)[i]);
BoundingBox.addInternalPoint(static_cast<const T *>(vertices)[i].Pos);
auto *vt = static_cast<const T *>(vertices);
Vertices->Data.insert(Vertices->Data.end(), vt, vt + numVertices);
for (u32 i = vertexCount; i < getVertexCount(); i++)
BoundingBox.addInternalPoint(Vertices->getPosition(i));
Indices->Data.insert(Indices->Data.end(), indices, indices + numIndices);
if (vertexCount != 0) {
for (u32 i = indexCount; i < getIndexCount(); i++)
Indices->Data[i] += vertexCount;
}
Indices.reallocate(getIndexCount() + numIndices);
for (i = 0; i < numIndices; ++i) {
Indices.push_back(indices[i] + vertexCount);
}
}
//! get the current hardware mapping hint
E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const override
{
return MappingHint_Vertex;
}
//! get the current hardware mapping hint
E_HARDWARE_MAPPING getHardwareMappingHint_Index() const override
{
return MappingHint_Index;
}
//! set the hardware mapping hint, for driver
void setHardwareMappingHint(E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer = EBT_VERTEX_AND_INDEX) override
{
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_VERTEX)
MappingHint_Vertex = NewMappingHint;
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_INDEX)
MappingHint_Index = NewMappingHint;
}
//! Describe what kind of primitive geometry is used by the meshbuffer
@ -217,47 +130,12 @@ public:
return PrimitiveType;
}
//! flags the mesh as changed, reloads hardware buffers
void setDirty(E_BUFFER_TYPE Buffer = EBT_VERTEX_AND_INDEX) override
{
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_VERTEX)
++ChangedID_Vertex;
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_INDEX)
++ChangedID_Index;
}
//! Get the currently used ID for identification of changes.
/** This shouldn't be used for anything outside the VideoDriver. */
u32 getChangedID_Vertex() const override { return ChangedID_Vertex; }
//! Get the currently used ID for identification of changes.
/** This shouldn't be used for anything outside the VideoDriver. */
u32 getChangedID_Index() const override { return ChangedID_Index; }
void setHWBuffer(void *ptr) const override
{
HWBuffer = ptr;
}
void *getHWBuffer() const override
{
return HWBuffer;
}
u32 ChangedID_Vertex;
u32 ChangedID_Index;
//! hardware mapping hint
E_HARDWARE_MAPPING MappingHint_Vertex;
E_HARDWARE_MAPPING MappingHint_Index;
mutable void *HWBuffer;
//! Material for this meshbuffer.
video::SMaterial Material;
//! Vertices of this buffer
core::array<T> Vertices;
//! Indices into the vertices of this buffer.
core::array<u16> Indices;
//! Vertex buffer
CVertexBuffer<T> *Vertices;
//! Index buffer
SIndexBuffer *Indices;
//! Bounding box of this meshbuffer.
core::aabbox3d<f32> BoundingBox;
//! Primitive type used for rendering (triangles, lines, ...)

122
irr/include/CVertexBuffer.h Normal file
View file

@ -0,0 +1,122 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include <vector>
#include "IVertexBuffer.h"
namespace irr
{
namespace scene
{
//! Template implementation of the IVertexBuffer interface
template <class T>
class CVertexBuffer final : public IVertexBuffer
{
public:
//! Default constructor for empty buffer
CVertexBuffer()
{
#ifdef _DEBUG
setDebugName("CVertexBuffer");
#endif
}
const void *getData() const override
{
return Data.data();
}
void *getData() override
{
return Data.data();
}
u32 getCount() const override
{
return static_cast<u32>(Data.size());
}
video::E_VERTEX_TYPE getType() const override
{
return T::getType();
}
const core::vector3df &getPosition(u32 i) const override
{
return Data[i].Pos;
}
core::vector3df &getPosition(u32 i) override
{
return Data[i].Pos;
}
const core::vector3df &getNormal(u32 i) const override
{
return Data[i].Normal;
}
core::vector3df &getNormal(u32 i) override
{
return Data[i].Normal;
}
const core::vector2df &getTCoords(u32 i) const override
{
return Data[i].TCoords;
}
core::vector2df &getTCoords(u32 i) override
{
return Data[i].TCoords;
}
E_HARDWARE_MAPPING getHardwareMappingHint() const override
{
return MappingHint;
}
void setHardwareMappingHint(E_HARDWARE_MAPPING NewMappingHint) override
{
MappingHint = NewMappingHint;
}
void setDirty() override
{
++ChangedID;
}
u32 getChangedID() const override { return ChangedID; }
void setHWBuffer(void *ptr) const override
{
HWBuffer = ptr;
}
void *getHWBuffer() const override
{
return HWBuffer;
}
u32 ChangedID = 1;
//! hardware mapping hint
E_HARDWARE_MAPPING MappingHint = EHM_NEVER;
mutable void *HWBuffer = nullptr;
//! Vertices of this buffer
std::vector<T> Data;
};
//! Standard buffer
typedef CVertexBuffer<video::S3DVertex> SVertexBuffer;
//! Buffer with two texture coords per vertex, e.g. for lightmaps
typedef CVertexBuffer<video::S3DVertex2TCoords> SVertexBufferLightMap;
//! Buffer with vertices having tangents stored, e.g. for normal mapping
typedef CVertexBuffer<video::S3DVertexTangents> SVertexBufferTangents;
} // end namespace scene
} // end namespace irr

View file

@ -24,9 +24,6 @@ enum E_DRIVER_TYPE
primitives. */
EDT_OPENGL,
//! OpenGL-ES 1.x driver, for embedded and mobile systems
EDT_OGLES1,
//! OpenGL-ES 2.x driver, for embedded and mobile systems
/** Supports shaders etc. */
EDT_OGLES2,

75
irr/include/EVideoTypes.h Normal file
View file

@ -0,0 +1,75 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "SMaterial.h" // MATERIAL_MAX_TEXTURES
namespace irr::video
{
//! enumeration for geometry transformation states
enum E_TRANSFORMATION_STATE
{
//! View transformation
ETS_VIEW = 0,
//! World transformation
ETS_WORLD,
//! Projection transformation
ETS_PROJECTION,
//! Texture 0 transformation
//! Use E_TRANSFORMATION_STATE(ETS_TEXTURE_0 + texture_number) to access other texture transformations
ETS_TEXTURE_0,
//! Only used internally
ETS_COUNT = ETS_TEXTURE_0 + MATERIAL_MAX_TEXTURES
};
//! Special render targets, which usually map to dedicated hardware
/** These render targets (besides 0 and 1) need not be supported by gfx cards */
enum E_RENDER_TARGET
{
//! Render target is the main color frame buffer
ERT_FRAME_BUFFER = 0,
//! Render target is a render texture
ERT_RENDER_TEXTURE,
//! Multi-Render target textures
ERT_MULTI_RENDER_TEXTURES,
//! Render target is the main color frame buffer
ERT_STEREO_LEFT_BUFFER,
//! Render target is the right color buffer (left is the main buffer)
ERT_STEREO_RIGHT_BUFFER,
//! Render to both stereo buffers at once
ERT_STEREO_BOTH_BUFFERS,
//! Auxiliary buffer 0
ERT_AUX_BUFFER0,
//! Auxiliary buffer 1
ERT_AUX_BUFFER1,
//! Auxiliary buffer 2
ERT_AUX_BUFFER2,
//! Auxiliary buffer 3
ERT_AUX_BUFFER3,
//! Auxiliary buffer 4
ERT_AUX_BUFFER4
};
//! Enum for the flags of clear buffer
enum E_CLEAR_BUFFER_FLAG
{
ECBF_NONE = 0,
ECBF_COLOR = 1,
ECBF_DEPTH = 2,
ECBF_STENCIL = 4,
ECBF_ALL = ECBF_COLOR | ECBF_DEPTH | ECBF_STENCIL
};
//! Enum for the types of fog distributions to choose from
enum E_FOG_TYPE
{
EFT_FOG_EXP = 0,
EFT_FOG_LINEAR,
EFT_FOG_EXP2
};
} // irr::video

View file

@ -23,27 +23,13 @@ namespace io
class IAttributes : public virtual IReferenceCounted
{
public:
//! Returns amount of attributes in this collection of attributes.
virtual u32 getAttributeCount() const = 0;
//! Returns attribute name by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
virtual const c8 *getAttributeName(s32 index) const = 0;
//! Returns the type of an attribute
//! \param attributeName: Name for the attribute
virtual E_ATTRIBUTE_TYPE getAttributeType(const c8 *attributeName) const = 0;
//! Returns attribute type by index.
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
virtual E_ATTRIBUTE_TYPE getAttributeType(s32 index) const = 0;
//! Returns if an attribute with a name exists
virtual bool existsAttribute(const c8 *attributeName) const = 0;
//! Returns attribute index from name, -1 if not found
virtual s32 findAttribute(const c8 *attributeName) const = 0;
//! Removes all attributes
virtual void clear() = 0;
@ -65,13 +51,6 @@ public:
//! \return Returns value of the attribute previously set by setAttribute()
virtual s32 getAttributeAsInt(const c8 *attributeName, irr::s32 defaultNotFound = 0) const = 0;
//! Gets an attribute as integer value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
virtual s32 getAttributeAsInt(s32 index) const = 0;
//! Sets an attribute as integer value
virtual void setAttribute(s32 index, s32 value) = 0;
/*
Float Attribute
@ -90,13 +69,6 @@ public:
//! \return Returns value of the attribute previously set by setAttribute()
virtual f32 getAttributeAsFloat(const c8 *attributeName, irr::f32 defaultNotFound = 0.f) const = 0;
//! Gets an attribute as float value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
virtual f32 getAttributeAsFloat(s32 index) const = 0;
//! Sets an attribute as float value
virtual void setAttribute(s32 index, f32 value) = 0;
/*
Bool Attribute
*/
@ -112,13 +84,6 @@ public:
//! \param defaultNotFound Value returned when attributeName was not found
//! \return Returns value of the attribute previously set by setAttribute()
virtual bool getAttributeAsBool(const c8 *attributeName, bool defaultNotFound = false) const = 0;
//! Gets an attribute as boolean value
//! \param index: Index value, must be between 0 and getAttributeCount()-1.
virtual bool getAttributeAsBool(s32 index) const = 0;
//! Sets an attribute as boolean value
virtual void setAttribute(s32 index, bool value) = 0;
};
} // end namespace io

View file

@ -85,113 +85,6 @@ public:
See IReferenceCounted::drop() for more information. */
virtual IWriteFile *createAndWriteFile(const path &filename, bool append = false) = 0;
//! Adds an archive to the file system.
/** After calling this, the Irrlicht Engine will also search and open
files directly from this archive. This is useful for hiding data from
the end user, speeding up file access and making it possible to access
for example Quake3 .pk3 files, which are just renamed .zip files. By
default Irrlicht supports ZIP, PAK, TAR, PNK, and directories as
archives. You can provide your own archive types by implementing
IArchiveLoader and passing an instance to addArchiveLoader.
Irrlicht supports AES-encrypted zip files, and the advanced compression
techniques lzma and bzip2.
\param filename: Filename of the archive to add to the file system.
\param ignoreCase: If set to true, files in the archive can be accessed without
writing all letters in the right case.
\param ignorePaths: If set to true, files in the added archive can be accessed
without its complete path.
\param archiveType: If no specific E_FILE_ARCHIVE_TYPE is selected then
the type of archive will depend on the extension of the file name. If
you use a different extension then you can use this parameter to force
a specific type of archive.
\param password An optional password, which is used in case of encrypted archives.
\param retArchive A pointer that will be set to the archive that is added.
\return True if the archive was added successfully, false if not. */
virtual bool addFileArchive(const path &filename, bool ignoreCase = true,
bool ignorePaths = true,
E_FILE_ARCHIVE_TYPE archiveType = EFAT_UNKNOWN,
const core::stringc &password = "",
IFileArchive **retArchive = 0) = 0;
//! Adds an archive to the file system.
/** After calling this, the Irrlicht Engine will also search and open
files directly from this archive. This is useful for hiding data from
the end user, speeding up file access and making it possible to access
for example Quake3 .pk3 files, which are just renamed .zip files. By
default Irrlicht supports ZIP, PAK, TAR, PNK, and directories as
archives. You can provide your own archive types by implementing
IArchiveLoader and passing an instance to addArchiveLoader.
Irrlicht supports AES-encrypted zip files, and the advanced compression
techniques lzma and bzip2.
If you want to add a directory as an archive, prefix its name with a
slash in order to let Irrlicht recognize it as a folder mount (mypath/).
Using this technique one can build up a search order, because archives
are read first, and can be used more easily with relative filenames.
\param file: Archive to add to the file system.
\param ignoreCase: If set to true, files in the archive can be accessed without
writing all letters in the right case.
\param ignorePaths: If set to true, files in the added archive can be accessed
without its complete path.
\param archiveType: If no specific E_FILE_ARCHIVE_TYPE is selected then
the type of archive will depend on the extension of the file name. If
you use a different extension then you can use this parameter to force
a specific type of archive.
\param password An optional password, which is used in case of encrypted archives.
\param retArchive A pointer that will be set to the archive that is added.
\return True if the archive was added successfully, false if not. */
virtual bool addFileArchive(IReadFile *file, bool ignoreCase = true,
bool ignorePaths = true,
E_FILE_ARCHIVE_TYPE archiveType = EFAT_UNKNOWN,
const core::stringc &password = "",
IFileArchive **retArchive = 0) = 0;
//! Adds an archive to the file system.
/** \param archive: The archive to add to the file system.
\return True if the archive was added successfully, false if not. */
virtual bool addFileArchive(IFileArchive *archive) = 0;
//! Get the number of archives currently attached to the file system
virtual u32 getFileArchiveCount() const = 0;
//! Removes an archive from the file system.
/** This will close the archive and free any file handles, but will not
close resources which have already been loaded and are now cached, for
example textures and meshes.
\param index: The index of the archive to remove
\return True on success, false on failure */
virtual bool removeFileArchive(u32 index) = 0;
//! Removes an archive from the file system.
/** This will close the archive and free any file handles, but will not
close resources which have already been loaded and are now cached, for
example textures and meshes. Note that a relative filename might be
interpreted differently on each call, depending on the current working
directory. In case you want to remove an archive that was added using
a relative path name, you have to change to the same working directory
again. This means, that the filename given on creation is not an
identifier for the archive, but just a usual filename that is used for
locating the archive to work with.
\param filename The archive pointed to by the name will be removed
\return True on success, false on failure */
virtual bool removeFileArchive(const path &filename) = 0;
//! Removes an archive from the file system.
/** This will close the archive and free any file handles, but will not
close resources which have already been loaded and are now cached, for
example textures and meshes.
\param archive The archive to remove.
\return True on success, false on failure */
virtual bool removeFileArchive(const IFileArchive *archive) = 0;
//! Changes the search order of attached archives.
/**
\param sourceIndex: The index of the archive to change
\param relative: The relative change in position, archives with a lower index are searched first */
virtual bool moveFileArchive(u32 sourceIndex, s32 relative) = 0;
//! Get the archive at a given index.
virtual IFileArchive *getFileArchive(u32 index) = 0;
//! Adds an external archive loader to the engine.
/** Use this function to add support for new archive types to the
engine, for example proprietary or encrypted file storage. */

View file

@ -7,45 +7,39 @@
#include "IReferenceCounted.h"
#include "irrArray.h"
#include "EHardwareBufferFlags.h"
#include "EPrimitiveTypes.h"
#include "SVertexIndex.h"
namespace irr
{
namespace video
{
}
namespace scene
{
class IIndexBuffer : public virtual IReferenceCounted
{
public:
//! Get type of index data which is stored in this meshbuffer.
/** \return Index type of this buffer. */
virtual video::E_INDEX_TYPE getType() const = 0;
//! Get access to indices.
/** \return Pointer to indices array. */
virtual const void *getData() const = 0;
//! Get access to indices.
/** \return Pointer to indices array. */
virtual void *getData() = 0;
virtual video::E_INDEX_TYPE getType() const = 0;
virtual void setType(video::E_INDEX_TYPE IndexType) = 0;
virtual u32 stride() const = 0;
virtual u32 size() const = 0;
virtual void push_back(const u32 &element) = 0;
virtual u32 operator[](u32 index) const = 0;
virtual u32 getLast() = 0;
virtual void setValue(u32 index, u32 value) = 0;
virtual void set_used(u32 usedNow) = 0;
virtual void reallocate(u32 new_size) = 0;
virtual u32 allocated_size() const = 0;
virtual void *pointer() = 0;
//! Get amount of indices in this meshbuffer.
/** \return Number of indices in this buffer. */
virtual u32 getCount() const = 0;
//! get the current hardware mapping hint
virtual E_HARDWARE_MAPPING getHardwareMappingHint() const = 0;
//! set the hardware mapping hint, for driver
virtual void setHardwareMappingHint(E_HARDWARE_MAPPING NewMappingHint) = 0;
virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint) = 0;
//! flags the meshbuffer as changed, reloads hardware buffers
virtual void setDirty() = 0;
@ -53,6 +47,35 @@ public:
//! Get the currently used ID for identification of changes.
/** This shouldn't be used for anything outside the VideoDriver. */
virtual u32 getChangedID() const = 0;
//! Used by the VideoDriver to remember the buffer link.
virtual void setHWBuffer(void *ptr) const = 0;
virtual void *getHWBuffer() const = 0;
//! Calculate how many geometric primitives would be drawn
u32 getPrimitiveCount(E_PRIMITIVE_TYPE primitiveType) const
{
const u32 indexCount = getCount();
switch (primitiveType) {
case scene::EPT_POINTS:
return indexCount;
case scene::EPT_LINE_STRIP:
return indexCount - 1;
case scene::EPT_LINE_LOOP:
return indexCount;
case scene::EPT_LINES:
return indexCount / 2;
case scene::EPT_TRIANGLE_STRIP:
return (indexCount - 2);
case scene::EPT_TRIANGLE_FAN:
return (indexCount - 2);
case scene::EPT_TRIANGLES:
return indexCount / 3;
case scene::EPT_POINT_SPRITES:
return indexCount;
}
return 0;
}
};
} // end namespace scene

View file

@ -86,6 +86,17 @@ public:
mesh buffer. */
virtual IMeshBuffer *getMeshBuffer(const video::SMaterial &material) const = 0;
//! Minetest binds textures (node tiles, object textures) to models.
// glTF allows multiple primitives (mesh buffers) to reference the same texture.
// This is reflected here: This function gets the texture slot for a mesh buffer.
/** \param meshbufNr: Zero based index of the mesh buffer. The maximum value is
getMeshBufferCount() - 1;
\return number of texture slot to bind to the given mesh buffer */
virtual u32 getTextureSlot(u32 meshbufNr) const
{
return meshbufNr;
}
//! Get an axis aligned bounding box of the mesh.
/** \return Bounding box of this mesh. */
virtual const core::aabbox3d<f32> &getBoundingBox() const = 0;

View file

@ -7,8 +7,8 @@
#include "IReferenceCounted.h"
#include "SMaterial.h"
#include "aabbox3d.h"
#include "S3DVertex.h"
#include "SVertexIndex.h"
#include "IVertexBuffer.h"
#include "IIndexBuffer.h"
#include "EHardwareBufferFlags.h"
#include "EPrimitiveTypes.h"
@ -46,39 +46,17 @@ public:
/** \return Material of this buffer. */
virtual const video::SMaterial &getMaterial() const = 0;
//! Get type of vertex data which is stored in this meshbuffer.
/** \return Vertex type of this buffer. */
virtual video::E_VERTEX_TYPE getVertexType() const = 0;
/// Get the vertex buffer
virtual const scene::IVertexBuffer *getVertexBuffer() const = 0;
//! Get access to vertex data. The data is an array of vertices.
/** Which vertex type is used can be determined by getVertexType().
\return Pointer to array of vertices. */
virtual const void *getVertices() const = 0;
/// Get the vertex buffer
virtual scene::IVertexBuffer *getVertexBuffer() = 0;
//! Get access to vertex data. The data is an array of vertices.
/** Which vertex type is used can be determined by getVertexType().
\return Pointer to array of vertices. */
virtual void *getVertices() = 0;
/// Get the index buffer
virtual const scene::IIndexBuffer *getIndexBuffer() const = 0;
//! Get amount of vertices in meshbuffer.
/** \return Number of vertices in this buffer. */
virtual u32 getVertexCount() const = 0;
//! Get type of index data which is stored in this meshbuffer.
/** \return Index type of this buffer. */
virtual video::E_INDEX_TYPE getIndexType() const = 0;
//! Get access to indices.
/** \return Pointer to indices array. */
virtual const u16 *getIndices() const = 0;
//! Get access to indices.
/** \return Pointer to indices array. */
virtual u16 *getIndices() = 0;
//! Get amount of indices in this meshbuffer.
/** \return Number of indices in this buffer. */
virtual u32 getIndexCount() const = 0;
/// Get the index buffer
virtual scene::IIndexBuffer *getIndexBuffer() = 0;
//! Get the axis aligned bounding box of this meshbuffer.
/** \return Axis aligned bounding box of this buffer. */
@ -92,24 +70,6 @@ public:
//! Recalculates the bounding box. Should be called if the mesh changed.
virtual void recalculateBoundingBox() = 0;
//! returns position of vertex i
virtual const core::vector3df &getPosition(u32 i) const = 0;
//! returns position of vertex i
virtual core::vector3df &getPosition(u32 i) = 0;
//! returns normal of vertex i
virtual const core::vector3df &getNormal(u32 i) const = 0;
//! returns normal of vertex i
virtual core::vector3df &getNormal(u32 i) = 0;
//! returns texture coord of vertex i
virtual const core::vector2df &getTCoords(u32 i) const = 0;
//! returns texture coord of vertex i
virtual core::vector2df &getTCoords(u32 i) = 0;
//! Append the vertices and indices to the current buffer
/** Only works for compatible vertex types.
\param vertices Pointer to a vertex array.
@ -118,29 +78,123 @@ public:
\param numIndices Number of indices in array. */
virtual void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) = 0;
//! get the current hardware mapping hint
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const = 0;
/* Leftover functions that are now just helpers for accessing the respective buffer. */
//! get the current hardware mapping hint
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const = 0;
//! Get type of vertex data which is stored in this meshbuffer.
/** \return Vertex type of this buffer. */
inline video::E_VERTEX_TYPE getVertexType() const
{
return getVertexBuffer()->getType();
}
//! Get access to vertex data. The data is an array of vertices.
/** Which vertex type is used can be determined by getVertexType().
\return Pointer to array of vertices. */
inline const void *getVertices() const
{
return getVertexBuffer()->getData();
}
//! Get access to vertex data. The data is an array of vertices.
/** Which vertex type is used can be determined by getVertexType().
\return Pointer to array of vertices. */
inline void *getVertices()
{
return getVertexBuffer()->getData();
}
//! Get amount of vertices in meshbuffer.
/** \return Number of vertices in this buffer. */
inline u32 getVertexCount() const
{
return getVertexBuffer()->getCount();
}
//! Get type of index data which is stored in this meshbuffer.
/** \return Index type of this buffer. */
inline video::E_INDEX_TYPE getIndexType() const
{
return getIndexBuffer()->getType();
}
//! Get access to indices.
/** \return Pointer to indices array. */
inline const u16 *getIndices() const
{
_IRR_DEBUG_BREAK_IF(getIndexBuffer()->getType() != video::EIT_16BIT);
return static_cast<const u16*>(getIndexBuffer()->getData());
}
//! Get access to indices.
/** \return Pointer to indices array. */
inline u16 *getIndices()
{
_IRR_DEBUG_BREAK_IF(getIndexBuffer()->getType() != video::EIT_16BIT);
return static_cast<u16*>(getIndexBuffer()->getData());
}
//! Get amount of indices in this meshbuffer.
/** \return Number of indices in this buffer. */
inline u32 getIndexCount() const
{
return getIndexBuffer()->getCount();
}
//! returns position of vertex i
inline const core::vector3df &getPosition(u32 i) const
{
return getVertexBuffer()->getPosition(i);
}
//! returns position of vertex i
inline core::vector3df &getPosition(u32 i)
{
return getVertexBuffer()->getPosition(i);
}
//! returns normal of vertex i
inline const core::vector3df &getNormal(u32 i) const
{
return getVertexBuffer()->getNormal(i);
}
//! returns normal of vertex i
inline core::vector3df &getNormal(u32 i)
{
return getVertexBuffer()->getNormal(i);
}
//! returns texture coord of vertex i
inline const core::vector2df &getTCoords(u32 i) const
{
return getVertexBuffer()->getTCoords(i);
}
//! returns texture coord of vertex i
inline core::vector2df &getTCoords(u32 i)
{
return getVertexBuffer()->getTCoords(i);
}
//! set the hardware mapping hint, for driver
virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) = 0;
inline void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX)
{
if (buffer == EBT_VERTEX_AND_INDEX || buffer == EBT_VERTEX)
getVertexBuffer()->setHardwareMappingHint(newMappingHint);
if (buffer == EBT_VERTEX_AND_INDEX || buffer == EBT_INDEX)
getIndexBuffer()->setHardwareMappingHint(newMappingHint);
}
//! flags the meshbuffer as changed, reloads hardware buffers
virtual void setDirty(E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) = 0;
inline void setDirty(E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX)
{
if (buffer == EBT_VERTEX_AND_INDEX || buffer == EBT_VERTEX)
getVertexBuffer()->setDirty();
if (buffer == EBT_VERTEX_AND_INDEX || buffer == EBT_INDEX)
getIndexBuffer()->setDirty();
}
//! Get the currently used ID for identification of changes.
/** This shouldn't be used for anything outside the VideoDriver. */
virtual u32 getChangedID_Vertex() const = 0;
//! Get the currently used ID for identification of changes.
/** This shouldn't be used for anything outside the VideoDriver. */
virtual u32 getChangedID_Index() const = 0;
//! Used by the VideoDriver to remember the buffer link.
virtual void setHWBuffer(void *ptr) const = 0;
virtual void *getHWBuffer() const = 0;
/* End helpers */
//! Describe what kind of primitive geometry is used by the meshbuffer
/** Note: Default is EPT_TRIANGLES. Using other types is fine for rendering.
@ -153,32 +207,13 @@ public:
virtual E_PRIMITIVE_TYPE getPrimitiveType() const = 0;
//! Calculate how many geometric primitives are used by this meshbuffer
virtual u32 getPrimitiveCount() const
u32 getPrimitiveCount() const
{
const u32 indexCount = getIndexCount();
switch (getPrimitiveType()) {
case scene::EPT_POINTS:
return indexCount;
case scene::EPT_LINE_STRIP:
return indexCount - 1;
case scene::EPT_LINE_LOOP:
return indexCount;
case scene::EPT_LINES:
return indexCount / 2;
case scene::EPT_TRIANGLE_STRIP:
return (indexCount - 2);
case scene::EPT_TRIANGLE_FAN:
return (indexCount - 2);
case scene::EPT_TRIANGLES:
return indexCount / 3;
case scene::EPT_POINT_SPRITES:
return indexCount;
}
return 0;
return getIndexBuffer()->getPrimitiveCount(getPrimitiveType());
}
//! Calculate size of vertices and indices in memory
virtual size_t getSize() const
size_t getSize() const
{
size_t ret = 0;
switch (getVertexType()) {

View file

@ -51,6 +51,10 @@ public:
{
}
// Reference counted objects can be neither copied nor moved.
IReferenceCounted(const IReferenceCounted &) = delete;
IReferenceCounted &operator=(const IReferenceCounted &) = delete;
//! Grabs the object. Increments the reference counter by one.
/** Someone who calls grab() to an object, should later also
call drop() to it. If an object never gets as much drop() as

View file

@ -10,6 +10,7 @@
#include "EDebugSceneTypes.h"
#include "SMaterial.h"
#include "irrString.h"
#include "irrArray.h"
#include "aabbox3d.h"
#include "matrix4.h"
#include "IAttributes.h"

View file

@ -199,6 +199,9 @@ public:
//! Adds a new meshbuffer to the mesh, access it as last one
virtual SSkinMeshBuffer *addMeshBuffer() = 0;
//! Adds a new meshbuffer to the mesh, access it as last one
virtual void addMeshBuffer(SSkinMeshBuffer *meshbuf) = 0;
//! Adds a new joint to the mesh, access it as last one
virtual SJoint *addJoint(SJoint *parent = 0) = 0;

View file

@ -17,24 +17,47 @@ namespace scene
class IVertexBuffer : public virtual IReferenceCounted
{
public:
virtual void *getData() = 0;
//! Get type of vertex data which is stored in this meshbuffer.
/** \return Vertex type of this buffer. */
virtual video::E_VERTEX_TYPE getType() const = 0;
virtual void setType(video::E_VERTEX_TYPE vertexType) = 0;
virtual u32 stride() const = 0;
virtual u32 size() const = 0;
virtual void push_back(const video::S3DVertex &element) = 0;
virtual video::S3DVertex &operator[](const u32 index) const = 0;
virtual video::S3DVertex &getLast() = 0;
virtual void set_used(u32 usedNow) = 0;
virtual void reallocate(u32 new_size) = 0;
virtual u32 allocated_size() const = 0;
virtual video::S3DVertex *pointer() = 0;
//! Get access to vertex data. The data is an array of vertices.
/** Which vertex type is used can be determined by getVertexType().
\return Pointer to array of vertices. */
virtual const void *getData() const = 0;
//! Get access to vertex data. The data is an array of vertices.
/** Which vertex type is used can be determined by getVertexType().
\return Pointer to array of vertices. */
virtual void *getData() = 0;
//! Get amount of vertices in meshbuffer.
/** \return Number of vertices in this buffer. */
virtual u32 getCount() const = 0;
//! returns position of vertex i
virtual const core::vector3df &getPosition(u32 i) const = 0;
//! returns position of vertex i
virtual core::vector3df &getPosition(u32 i) = 0;
//! returns normal of vertex i
virtual const core::vector3df &getNormal(u32 i) const = 0;
//! returns normal of vertex i
virtual core::vector3df &getNormal(u32 i) = 0;
//! returns texture coord of vertex i
virtual const core::vector2df &getTCoords(u32 i) const = 0;
//! returns texture coord of vertex i
virtual core::vector2df &getTCoords(u32 i) = 0;
//! get the current hardware mapping hint
virtual E_HARDWARE_MAPPING getHardwareMappingHint() const = 0;
//! set the hardware mapping hint, for driver
virtual void setHardwareMappingHint(E_HARDWARE_MAPPING NewMappingHint) = 0;
virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint) = 0;
//! flags the meshbuffer as changed, reloads hardware buffers
virtual void setDirty() = 0;
@ -42,6 +65,10 @@ public:
//! Get the currently used ID for identification of changes.
/** This shouldn't be used for anything outside the VideoDriver. */
virtual u32 getChangedID() const = 0;
//! Used by the VideoDriver to remember the buffer link.
virtual void setHWBuffer(void *ptr) const = 0;
virtual void *getHWBuffer() const = 0;
};
} // end namespace scene

View file

@ -9,14 +9,16 @@
#include "ITexture.h"
#include "irrArray.h"
#include "matrix4.h"
#include "plane3d.h"
#include "dimension2d.h"
#include "position2d.h"
#include "IMeshBuffer.h"
#include "EDriverTypes.h"
#include "EDriverFeatures.h"
#include "EPrimitiveTypes.h"
#include "EVideoTypes.h"
#include "SExposedVideoData.h"
#include "SOverrideMaterial.h"
#include "S3DVertex.h" // E_VERTEX_TYPE
#include "SVertexIndex.h" // E_INDEX_TYPE
namespace irr
{
@ -29,6 +31,8 @@ class IWriteFile;
namespace scene
{
class IMeshBuffer;
class IVertexBuffer;
class IIndexBuffer;
class IMesh;
class IMeshManipulator;
class ISceneNode;
@ -36,77 +40,12 @@ class ISceneNode;
namespace video
{
struct S3DVertex;
struct S3DVertex2TCoords;
struct S3DVertexTangents;
class IImageLoader;
class IImageWriter;
class IMaterialRenderer;
class IGPUProgrammingServices;
class IRenderTarget;
//! enumeration for geometry transformation states
enum E_TRANSFORMATION_STATE
{
//! View transformation
ETS_VIEW = 0,
//! World transformation
ETS_WORLD,
//! Projection transformation
ETS_PROJECTION,
//! Texture 0 transformation
//! Use E_TRANSFORMATION_STATE(ETS_TEXTURE_0 + texture_number) to access other texture transformations
ETS_TEXTURE_0,
//! Only used internally
ETS_COUNT = ETS_TEXTURE_0 + MATERIAL_MAX_TEXTURES
};
//! Special render targets, which usually map to dedicated hardware
/** These render targets (besides 0 and 1) need not be supported by gfx cards */
enum E_RENDER_TARGET
{
//! Render target is the main color frame buffer
ERT_FRAME_BUFFER = 0,
//! Render target is a render texture
ERT_RENDER_TEXTURE,
//! Multi-Render target textures
ERT_MULTI_RENDER_TEXTURES,
//! Render target is the main color frame buffer
ERT_STEREO_LEFT_BUFFER,
//! Render target is the right color buffer (left is the main buffer)
ERT_STEREO_RIGHT_BUFFER,
//! Render to both stereo buffers at once
ERT_STEREO_BOTH_BUFFERS,
//! Auxiliary buffer 0
ERT_AUX_BUFFER0,
//! Auxiliary buffer 1
ERT_AUX_BUFFER1,
//! Auxiliary buffer 2
ERT_AUX_BUFFER2,
//! Auxiliary buffer 3
ERT_AUX_BUFFER3,
//! Auxiliary buffer 4
ERT_AUX_BUFFER4
};
//! Enum for the flags of clear buffer
enum E_CLEAR_BUFFER_FLAG
{
ECBF_NONE = 0,
ECBF_COLOR = 1,
ECBF_DEPTH = 2,
ECBF_STENCIL = 4,
ECBF_ALL = ECBF_COLOR | ECBF_DEPTH | ECBF_STENCIL
};
//! Enum for the types of fog distributions to choose from
enum E_FOG_TYPE
{
EFT_FOG_EXP = 0,
EFT_FOG_LINEAR,
EFT_FOG_EXP2
};
const c8 *const FogTypeNames[] = {
"FogExp",
"FogLinear",
@ -114,6 +53,15 @@ const c8 *const FogTypeNames[] = {
0,
};
struct SFrameStats {
//! Count of primitives drawn
u32 PrimitivesDrawn = 0;
//! Number of hardware buffers uploaded (new or updated)
u32 HWBuffersUploaded = 0;
//! Sum of uploaded hardware buffer size
u32 HWBuffersUploadedSize = 0;
};
//! Interface to driver which is able to perform 2d and 3d graphics functions.
/** This interface is one of the most important interfaces of
the Irrlicht Engine: All rendering and texture manipulation is done with
@ -182,7 +130,6 @@ public:
MaxSupportedTextures (int) The maximum number of simultaneous textures supported by the fixed function pipeline of the (hw) driver. The actual supported number of textures supported by the engine can be lower.
MaxLights (int) Number of hardware lights supported in the fixed function pipeline of the driver, typically 6-8. Use light manager or deferred shading for more.
MaxAnisotropy (int) Number of anisotropy levels supported for filtering. At least 1, max is typically at 16 or 32.
MaxUserClipPlanes (int) Number of additional clip planes, which can be set by the user via dedicated driver methods.
MaxAuxBuffers (int) Special render buffers, which are currently not really usable inside Irrlicht. Only supported by OpenGL
MaxMultipleRenderTargets (int) Number of render targets which can be bound simultaneously. Rendering to MRTs is done via shaders.
MaxIndices (int) Number of indices which can be used in one render call (i.e. one mesh buffer).
@ -195,12 +142,6 @@ public:
*/
virtual const io::IAttributes &getDriverAttributes() const = 0;
//! Check if the driver was recently reset.
/** For d3d devices you will need to recreate the RTTs if the
driver was reset. Should be queried right after beginScene().
*/
virtual bool checkDriverReset() = 0;
//! Sets transformation matrices.
/** \param state Transformation type to be set, e.g. view,
world, or projection.
@ -360,7 +301,10 @@ public:
virtual void removeAllTextures() = 0;
//! Remove hardware buffer
virtual void removeHardwareBuffer(const scene::IMeshBuffer *mb) = 0;
virtual void removeHardwareBuffer(const scene::IVertexBuffer *vb) = 0;
//! Remove hardware buffer
virtual void removeHardwareBuffer(const scene::IIndexBuffer *ib) = 0;
//! Remove all hardware buffers
virtual void removeAllHardwareBuffers() = 0;
@ -799,6 +743,17 @@ public:
/** \param mb Buffer to draw */
virtual void drawMeshBuffer(const scene::IMeshBuffer *mb) = 0;
/**
* Draws a mesh from individual vertex and index buffers.
* @param vb vertices to use
* @param ib indices to use
* @param primCount amount of primitives
* @param pType primitive type
*/
virtual void drawBuffers(const scene::IVertexBuffer *vb,
const scene::IIndexBuffer *ib, u32 primCount,
scene::E_PRIMITIVE_TYPE pType = scene::EPT_TRIANGLES) = 0;
//! Draws normals of a mesh buffer
/** \param mb Buffer to draw the normals of
\param length length scale factor of the normals
@ -856,12 +811,8 @@ public:
\return Approximate amount of frames per second drawn. */
virtual s32 getFPS() const = 0;
//! Returns amount of primitives (mostly triangles) which were drawn in the last frame.
/** Together with getFPS() very useful method for statistics.
\param mode Defines if the primitives drawn are accumulated or
counted per frame.
\return Amount of primitives drawn in the last frame. */
virtual u32 getPrimitiveCountDrawn(u32 mode = 0) const = 0;
//! Return some statistics about the last frame
virtual SFrameStats getFrameStats() const = 0;
//! Gets name of this video driver.
/** \return Returns the name of the video driver, e.g. in case
@ -1109,26 +1060,6 @@ public:
\return Pointer to loaded texture, or 0 if not found. */
virtual video::ITexture *findTexture(const io::path &filename) = 0;
//! Set or unset a clipping plane.
/** There are at least 6 clipping planes available for the user
to set at will.
\param index The plane index. Must be between 0 and
MaxUserClipPlanes.
\param plane The plane itself.
\param enable If true, enable the clipping plane else disable
it.
\return True if the clipping plane is usable. */
virtual bool setClipPlane(u32 index, const core::plane3df &plane, bool enable = false) = 0;
//! Enable or disable a clipping plane.
/** There are at least 6 clipping planes available for the user
to set at will.
\param index The plane index. Must be between 0 and
MaxUserClipPlanes.
\param enable If true, enable the clipping plane else disable
it. */
virtual void enableClipPlane(u32 index, bool enable) = 0;
//! Set the minimum number of vertices for which a hw buffer will be created
/** \param count Number of vertices to set as minimum. */
virtual void setMinHardwareBufferVertexCount(u32 count) = 0;

View file

@ -6,14 +6,16 @@
#include "IReferenceCounted.h"
#include "dimension2d.h"
#include "IVideoDriver.h"
#include "EDriverTypes.h"
#include "EDeviceTypes.h"
#include "IEventReceiver.h"
#include "ICursorControl.h"
#include "ITimer.h"
#include "IOSOperator.h"
#include "irrArray.h"
#include "IrrCompileConfig.h"
#include "position2d.h"
#include "SColor.h" // video::ECOLOR_FORMAT
namespace irr
{
@ -38,6 +40,9 @@ class ISceneManager;
namespace video
{
class IContextManager;
class IImage;
class ITexture;
class IVideoDriver;
extern "C" IRRLICHT_API bool IRRCALLCONV isDriverSupported(E_DRIVER_TYPE driver);
} // end namespace video

View file

@ -4,10 +4,10 @@
#pragma once
#include <vector>
#include "IAnimatedMesh.h"
#include "IMesh.h"
#include "aabbox3d.h"
#include "irrArray.h"
namespace irr
{
@ -15,7 +15,7 @@ namespace scene
{
//! Simple implementation of the IAnimatedMesh interface.
struct SAnimatedMesh : public IAnimatedMesh
struct SAnimatedMesh final : public IAnimatedMesh
{
//! constructor
SAnimatedMesh(scene::IMesh *mesh = 0, scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) :
@ -32,15 +32,15 @@ struct SAnimatedMesh : public IAnimatedMesh
virtual ~SAnimatedMesh()
{
// drop meshes
for (u32 i = 0; i < Meshes.size(); ++i)
Meshes[i]->drop();
for (auto *mesh : Meshes)
mesh->drop();
}
//! Gets the frame count of the animated mesh.
/** \return Amount of frames. If the amount is 1, it is a static, non animated mesh. */
u32 getFrameCount() const override
{
return Meshes.size();
return static_cast<u32>(Meshes.size());
}
//! Gets the default animation speed of the animated mesh.
@ -161,7 +161,7 @@ struct SAnimatedMesh : public IAnimatedMesh
}
//! All meshes defining the animated mesh
core::array<IMesh *> Meshes;
std::vector<IMesh *> Meshes;
//! The bounding box of this mesh
core::aabbox3d<f32> Box;

View file

@ -6,7 +6,6 @@
#include "SColor.h"
#include "matrix4.h"
#include "irrArray.h"
#include "irrMath.h"
#include "EMaterialTypes.h"
#include "EMaterialProps.h"

View file

@ -4,17 +4,17 @@
#pragma once
#include <vector>
#include "IMesh.h"
#include "IMeshBuffer.h"
#include "aabbox3d.h"
#include "irrArray.h"
namespace irr
{
namespace scene
{
//! Simple implementation of the IMesh interface.
struct SMesh : public IMesh
struct SMesh final : public IMesh
{
//! constructor
SMesh()
@ -28,15 +28,15 @@ struct SMesh : public IMesh
virtual ~SMesh()
{
// drop buffers
for (u32 i = 0; i < MeshBuffers.size(); ++i)
MeshBuffers[i]->drop();
for (auto *buf : MeshBuffers)
buf->drop();
}
//! clean mesh
virtual void clear()
{
for (u32 i = 0; i < MeshBuffers.size(); ++i)
MeshBuffers[i]->drop();
for (auto *buf : MeshBuffers)
buf->drop();
MeshBuffers.clear();
BoundingBox.reset(0.f, 0.f, 0.f);
}
@ -44,7 +44,7 @@ struct SMesh : public IMesh
//! returns amount of mesh buffers.
u32 getMeshBufferCount() const override
{
return MeshBuffers.size();
return static_cast<u32>(MeshBuffers.size());
}
//! returns pointer to a mesh buffer
@ -57,14 +57,24 @@ struct SMesh : public IMesh
/** reverse search */
IMeshBuffer *getMeshBuffer(const video::SMaterial &material) const override
{
for (s32 i = (s32)MeshBuffers.size() - 1; i >= 0; --i) {
if (material == MeshBuffers[i]->getMaterial())
return MeshBuffers[i];
for (auto it = MeshBuffers.rbegin(); it != MeshBuffers.rend(); it++) {
if (material == (*it)->getMaterial())
return *it;
}
return 0;
return nullptr;
}
u32 getTextureSlot(u32 meshbufNr) const override
{
return TextureSlots.at(meshbufNr);
}
void setTextureSlot(u32 meshbufNr, u32 textureSlot)
{
TextureSlots.at(meshbufNr) = textureSlot;
}
//! returns an axis aligned bounding box
const core::aabbox3d<f32> &getBoundingBox() const override
{
@ -81,8 +91,8 @@ struct SMesh : public IMesh
void recalculateBoundingBox()
{
bool hasMeshBufferBBox = false;
for (u32 i = 0; i < MeshBuffers.size(); ++i) {
const core::aabbox3df &bb = MeshBuffers[i]->getBoundingBox();
for (auto *buf : MeshBuffers) {
const core::aabbox3df &bb = buf->getBoundingBox();
if (!bb.isEmpty()) {
if (!hasMeshBufferBBox) {
hasMeshBufferBBox = true;
@ -104,25 +114,28 @@ struct SMesh : public IMesh
if (buf) {
buf->grab();
MeshBuffers.push_back(buf);
TextureSlots.push_back(getMeshBufferCount() - 1);
}
}
//! set the hardware mapping hint, for driver
void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override
{
for (u32 i = 0; i < MeshBuffers.size(); ++i)
MeshBuffers[i]->setHardwareMappingHint(newMappingHint, buffer);
for (auto *buf : MeshBuffers)
buf->setHardwareMappingHint(newMappingHint, buffer);
}
//! flags the meshbuffer as changed, reloads hardware buffers
void setDirty(E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override
{
for (u32 i = 0; i < MeshBuffers.size(); ++i)
MeshBuffers[i]->setDirty(buffer);
for (auto *buf : MeshBuffers)
buf->setDirty(buffer);
}
//! The meshbuffers of this mesh
core::array<IMeshBuffer *> MeshBuffers;
std::vector<IMeshBuffer *> MeshBuffers;
//! Mapping from meshbuffer number to bindable texture slot
std::vector<u32> TextureSlots;
//! The bounding box of this mesh
core::aabbox3d<f32> BoundingBox;

View file

@ -4,6 +4,7 @@
#pragma once
#include <vector>
#include "SMaterial.h"
namespace irr
@ -57,7 +58,7 @@ struct SOverrideMaterial
};
//! To overwrite SMaterial::MaterialType
core::array<SMaterialTypeReplacement> MaterialTypes;
std::vector<SMaterialTypeReplacement> MaterialTypes;
//! Default constructor
SOverrideMaterial() :
@ -83,9 +84,8 @@ struct SOverrideMaterial
void apply(SMaterial &material)
{
if (Enabled) {
for (u32 i = 0; i < MaterialTypes.size(); ++i) {
const SMaterialTypeReplacement &mtr = MaterialTypes[i];
if (mtr.Original < 0 || (s32)mtr.Original == material.MaterialType)
for (const auto &mtr : MaterialTypes) {
if (mtr.Original < 0 || mtr.Original == (s32)material.MaterialType)
material.MaterialType = (E_MATERIAL_TYPE)mtr.Replacement;
}
for (u32 f = 0; f < 32; ++f) {

View file

@ -5,7 +5,10 @@
#pragma once
#include "IMeshBuffer.h"
#include "CVertexBuffer.h"
#include "CIndexBuffer.h"
#include "S3DVertex.h"
#include "irrArray.h"
namespace irr
{
@ -13,19 +16,36 @@ namespace scene
{
//! A mesh buffer able to choose between S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
struct SSkinMeshBuffer : public IMeshBuffer
struct SSkinMeshBuffer final : public IMeshBuffer
{
//! Default constructor
SSkinMeshBuffer(video::E_VERTEX_TYPE vt = video::EVT_STANDARD) :
ChangedID_Vertex(1), ChangedID_Index(1), VertexType(vt),
PrimitiveType(EPT_TRIANGLES),
MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER),
HWBuffer(NULL),
VertexType(vt), PrimitiveType(EPT_TRIANGLES),
BoundingBoxNeedsRecalculated(true)
{
#ifdef _DEBUG
setDebugName("SSkinMeshBuffer");
#endif
Vertices_Tangents = new SVertexBufferTangents();
Vertices_2TCoords = new SVertexBufferLightMap();
Vertices_Standard = new SVertexBuffer();
Indices = new SIndexBuffer();
}
//! Constructor for standard vertices
SSkinMeshBuffer(std::vector<video::S3DVertex> &&vertices, std::vector<u16> &&indices) :
SSkinMeshBuffer()
{
Vertices_Standard->Data = std::move(vertices);
Indices->Data = std::move(indices);
}
~SSkinMeshBuffer()
{
Vertices_Tangents->drop();
Vertices_2TCoords->drop();
Vertices_Standard->drop();
Indices->drop();
}
//! Get Material of this buffer.
@ -40,83 +60,53 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Material;
}
const scene::IVertexBuffer *getVertexBuffer() const override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords;
case video::EVT_TANGENTS:
return Vertices_Tangents;
default:
return Vertices_Standard;
}
}
scene::IVertexBuffer *getVertexBuffer() override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords;
case video::EVT_TANGENTS:
return Vertices_Tangents;
default:
return Vertices_Standard;
}
}
const scene::IIndexBuffer *getIndexBuffer() const override
{
return Indices;
}
scene::IIndexBuffer *getIndexBuffer() override
{
return Indices;
}
//! Get standard vertex at given index
virtual video::S3DVertex *getVertex(u32 index)
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return (video::S3DVertex *)&Vertices_2TCoords[index];
return &Vertices_2TCoords->Data[index];
case video::EVT_TANGENTS:
return (video::S3DVertex *)&Vertices_Tangents[index];
return &Vertices_Tangents->Data[index];
default:
return &Vertices_Standard[index];
return &Vertices_Standard->Data[index];
}
}
//! Get pointer to vertex array
const void *getVertices() const override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords.const_pointer();
case video::EVT_TANGENTS:
return Vertices_Tangents.const_pointer();
default:
return Vertices_Standard.const_pointer();
}
}
//! Get pointer to vertex array
void *getVertices() override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords.pointer();
case video::EVT_TANGENTS:
return Vertices_Tangents.pointer();
default:
return Vertices_Standard.pointer();
}
}
//! Get vertex count
u32 getVertexCount() const override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords.size();
case video::EVT_TANGENTS:
return Vertices_Tangents.size();
default:
return Vertices_Standard.size();
}
}
//! Get type of index data which is stored in this meshbuffer.
/** \return Index type of this buffer. */
video::E_INDEX_TYPE getIndexType() const override
{
return video::EIT_16BIT;
}
//! Get pointer to index array
const u16 *getIndices() const override
{
return Indices.const_pointer();
}
//! Get pointer to index array
u16 *getIndices() override
{
return Indices.pointer();
}
//! Get index count
u32 getIndexCount() const override
{
return Indices.size();
}
//! Get bounding box
const core::aabbox3d<f32> &getBoundingBox() const override
{
@ -129,6 +119,28 @@ struct SSkinMeshBuffer : public IMeshBuffer
BoundingBox = box;
}
private:
template <typename T> void recalculateBoundingBox(const CVertexBuffer<T> *buf)
{
if (!buf->getCount()) {
BoundingBox.reset(0, 0, 0);
} else {
auto &vertices = buf->Data;
BoundingBox.reset(vertices[0].Pos);
for (size_t i = 1; i < vertices.size(); ++i)
BoundingBox.addInternalPoint(vertices[i].Pos);
}
}
template <typename T1, typename T2> static void copyVertex(const T1 &src, T2 &dst)
{
dst.Pos = src.Pos;
dst.Normal = src.Normal;
dst.Color = src.Color;
dst.TCoords = src.TCoords;
}
public:
//! Recalculate bounding box
void recalculateBoundingBox() override
{
@ -139,57 +151,30 @@ struct SSkinMeshBuffer : public IMeshBuffer
switch (VertexType) {
case video::EVT_STANDARD: {
if (Vertices_Standard.empty())
BoundingBox.reset(0, 0, 0);
else {
BoundingBox.reset(Vertices_Standard[0].Pos);
for (u32 i = 1; i < Vertices_Standard.size(); ++i)
BoundingBox.addInternalPoint(Vertices_Standard[i].Pos);
}
recalculateBoundingBox(Vertices_Standard);
break;
}
case video::EVT_2TCOORDS: {
if (Vertices_2TCoords.empty())
BoundingBox.reset(0, 0, 0);
else {
BoundingBox.reset(Vertices_2TCoords[0].Pos);
for (u32 i = 1; i < Vertices_2TCoords.size(); ++i)
BoundingBox.addInternalPoint(Vertices_2TCoords[i].Pos);
}
recalculateBoundingBox(Vertices_2TCoords);
break;
}
case video::EVT_TANGENTS: {
if (Vertices_Tangents.empty())
BoundingBox.reset(0, 0, 0);
else {
BoundingBox.reset(Vertices_Tangents[0].Pos);
for (u32 i = 1; i < Vertices_Tangents.size(); ++i)
BoundingBox.addInternalPoint(Vertices_Tangents[i].Pos);
}
recalculateBoundingBox(Vertices_Tangents);
break;
}
}
}
//! Get vertex type
video::E_VERTEX_TYPE getVertexType() const override
{
return VertexType;
}
//! Convert to 2tcoords vertex type
void convertTo2TCoords()
{
if (VertexType == video::EVT_STANDARD) {
for (u32 n = 0; n < Vertices_Standard.size(); ++n) {
video::S3DVertex2TCoords Vertex;
Vertex.Color = Vertices_Standard[n].Color;
Vertex.Pos = Vertices_Standard[n].Pos;
Vertex.Normal = Vertices_Standard[n].Normal;
Vertex.TCoords = Vertices_Standard[n].TCoords;
Vertices_2TCoords.push_back(Vertex);
video::S3DVertex2TCoords Vertex;
for (const auto &Vertex_Standard : Vertices_Standard->Data) {
copyVertex(Vertex_Standard, Vertex);
Vertices_2TCoords->Data.push_back(Vertex);
}
Vertices_Standard.clear();
Vertices_Standard->Data.clear();
VertexType = video::EVT_2TCOORDS;
}
}
@ -198,134 +183,28 @@ struct SSkinMeshBuffer : public IMeshBuffer
void convertToTangents()
{
if (VertexType == video::EVT_STANDARD) {
for (u32 n = 0; n < Vertices_Standard.size(); ++n) {
video::S3DVertexTangents Vertex;
Vertex.Color = Vertices_Standard[n].Color;
Vertex.Pos = Vertices_Standard[n].Pos;
Vertex.Normal = Vertices_Standard[n].Normal;
Vertex.TCoords = Vertices_Standard[n].TCoords;
Vertices_Tangents.push_back(Vertex);
video::S3DVertexTangents Vertex;
for (const auto &Vertex_Standard : Vertices_Standard->Data) {
copyVertex(Vertex_Standard, Vertex);
Vertices_Tangents->Data.push_back(Vertex);
}
Vertices_Standard.clear();
Vertices_Standard->Data.clear();
VertexType = video::EVT_TANGENTS;
} else if (VertexType == video::EVT_2TCOORDS) {
for (u32 n = 0; n < Vertices_2TCoords.size(); ++n) {
video::S3DVertexTangents Vertex;
Vertex.Color = Vertices_2TCoords[n].Color;
Vertex.Pos = Vertices_2TCoords[n].Pos;
Vertex.Normal = Vertices_2TCoords[n].Normal;
Vertex.TCoords = Vertices_2TCoords[n].TCoords;
Vertices_Tangents.push_back(Vertex);
video::S3DVertexTangents Vertex;
for (const auto &Vertex_2TCoords : Vertices_2TCoords->Data) {
copyVertex(Vertex_2TCoords, Vertex);
Vertices_Tangents->Data.push_back(Vertex);
}
Vertices_2TCoords.clear();
Vertices_2TCoords->Data.clear();
VertexType = video::EVT_TANGENTS;
}
}
//! returns position of vertex i
const core::vector3df &getPosition(u32 i) const override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords[i].Pos;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Pos;
default:
return Vertices_Standard[i].Pos;
}
}
//! returns position of vertex i
core::vector3df &getPosition(u32 i) override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords[i].Pos;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Pos;
default:
return Vertices_Standard[i].Pos;
}
}
//! returns normal of vertex i
const core::vector3df &getNormal(u32 i) const override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords[i].Normal;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Normal;
default:
return Vertices_Standard[i].Normal;
}
}
//! returns normal of vertex i
core::vector3df &getNormal(u32 i) override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords[i].Normal;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Normal;
default:
return Vertices_Standard[i].Normal;
}
}
//! returns texture coords of vertex i
const core::vector2df &getTCoords(u32 i) const override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords[i].TCoords;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].TCoords;
default:
return Vertices_Standard[i].TCoords;
}
}
//! returns texture coords of vertex i
core::vector2df &getTCoords(u32 i) override
{
switch (VertexType) {
case video::EVT_2TCOORDS:
return Vertices_2TCoords[i].TCoords;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].TCoords;
default:
return Vertices_Standard[i].TCoords;
}
}
//! append the vertices and indices to the current buffer
void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) override {}
//! get the current hardware mapping hint for vertex buffers
E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const override
void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) override
{
return MappingHint_Vertex;
}
//! get the current hardware mapping hint for index buffers
E_HARDWARE_MAPPING getHardwareMappingHint_Index() const override
{
return MappingHint_Index;
}
//! set the hardware mapping hint, for driver
void setHardwareMappingHint(E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer = EBT_VERTEX_AND_INDEX) override
{
if (Buffer == EBT_VERTEX)
MappingHint_Vertex = NewMappingHint;
else if (Buffer == EBT_INDEX)
MappingHint_Index = NewMappingHint;
else if (Buffer == EBT_VERTEX_AND_INDEX) {
MappingHint_Vertex = NewMappingHint;
MappingHint_Index = NewMappingHint;
}
_IRR_DEBUG_BREAK_IF(true);
}
//! Describe what kind of primitive geometry is used by the meshbuffer
@ -340,41 +219,14 @@ struct SSkinMeshBuffer : public IMeshBuffer
return PrimitiveType;
}
//! flags the mesh as changed, reloads hardware buffers
void setDirty(E_BUFFER_TYPE Buffer = EBT_VERTEX_AND_INDEX) override
{
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_VERTEX)
++ChangedID_Vertex;
if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_INDEX)
++ChangedID_Index;
}
u32 getChangedID_Vertex() const override { return ChangedID_Vertex; }
u32 getChangedID_Index() const override { return ChangedID_Index; }
void setHWBuffer(void *ptr) const override
{
HWBuffer = ptr;
}
void *getHWBuffer() const override
{
return HWBuffer;
}
//! Call this after changing the positions of any vertex.
void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; }
core::array<video::S3DVertexTangents> Vertices_Tangents;
core::array<video::S3DVertex2TCoords> Vertices_2TCoords;
core::array<video::S3DVertex> Vertices_Standard;
core::array<u16> Indices;
SVertexBufferTangents *Vertices_Tangents;
SVertexBufferLightMap *Vertices_2TCoords;
SVertexBuffer *Vertices_Standard;
SIndexBuffer *Indices;
u32 ChangedID_Vertex;
u32 ChangedID_Index;
// ISkinnedMesh::SJoint *AttachedJoint;
core::matrix4 Transformation;
video::SMaterial Material;
@ -385,13 +237,7 @@ struct SSkinMeshBuffer : public IMeshBuffer
//! Primitive type used for rendering (triangles, lines, ...)
E_PRIMITIVE_TYPE PrimitiveType;
// hardware mapping hint
E_HARDWARE_MAPPING MappingHint_Vertex : 3;
E_HARDWARE_MAPPING MappingHint_Index : 3;
mutable void *HWBuffer;
bool BoundingBoxNeedsRecalculated : 1;
bool BoundingBoxNeedsRecalculated;
};
} // end namespace scene

View file

@ -9,7 +9,7 @@
#include "line3d.h"
#include "aabbox3d.h"
#include "matrix4.h"
#include "IVideoDriver.h"
#include "EVideoTypes.h"
namespace irr
{

View file

@ -45,6 +45,10 @@ public:
{
}
//! Move constructor
array(std::vector<T> &&data) :
m_data(std::move(data)), is_sorted(false) {}
//! Reallocates the array, make it bigger or smaller.
/** \param new_size New size of array.
\param canShrink Specifies whether the array is reallocated even if
@ -167,13 +171,6 @@ public:
return *this;
}
array<T> &operator=(std::vector<T> &&other)
{
m_data = std::move(other);
is_sorted = false;
return *this;
}
//! Equality operator
bool operator==(const array<T> &other) const
{
@ -400,16 +397,6 @@ public:
std::swap(is_sorted, other.is_sorted);
}
//! Pull the contents of this array as a vector.
// The array is left empty.
std::vector<T> steal()
{
std::vector<T> ret = std::move(m_data);
m_data.clear();
is_sorted = true;
return ret;
}
typedef T value_type;
typedef u32 size_type;

View file

@ -11,7 +11,6 @@
#include <cstdio>
#include <cstring>
#include <cwchar>
#include <locale>
/* HACK: import these string methods from MT's util/string.h */
extern std::wstring utf8_to_wide(std::string_view input);
@ -65,6 +64,7 @@ static inline u32 locale_upper(u32 x)
template <typename T>
class string
{
using stl_type = std::basic_string<T>;
public:
typedef T char_type;
@ -79,6 +79,10 @@ public:
*this = other;
}
string(const stl_type &str) : str(str) {}
string(stl_type &&str) : str(std::move(str)) {}
//! Constructor from other string types
template <class B>
string(const string<B> &other)
@ -814,13 +818,6 @@ public:
friend size_t wStringToUTF8(stringc &destination, const wchar_t *source);
private:
typedef std::basic_string<T> stl_type;
//! Private constructor
string(stl_type &&str) :
str(str)
{
}
//! strlen wrapper
template <typename U>

Some files were not shown because too many files have changed in this diff Show more