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:
commit
8a841aee59
328 changed files with 8044 additions and 10079 deletions
45
.github/workflows/whitespace_checks.yml
vendored
Normal file
45
.github/workflows/whitespace_checks.yml
vendored
Normal 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
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,12 @@ files["builtin/client/register.lua"] = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
files["builtin/common/math.lua"] = {
|
||||||
|
globals = {
|
||||||
|
"math",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
files["builtin/common/misc_helpers.lua"] = {
|
files["builtin/common/misc_helpers.lua"] = {
|
||||||
globals = {
|
globals = {
|
||||||
"dump", "dump2", "table", "math", "string",
|
"dump", "dump2", "table", "math", "string",
|
||||||
|
@ -46,7 +52,7 @@ files["builtin/common/misc_helpers.lua"] = {
|
||||||
}
|
}
|
||||||
|
|
||||||
files["builtin/common/vector.lua"] = {
|
files["builtin/common/vector.lua"] = {
|
||||||
globals = { "vector" },
|
globals = { "vector", "math" },
|
||||||
}
|
}
|
||||||
|
|
||||||
files["builtin/game/voxelarea.lua"] = {
|
files["builtin/game/voxelarea.lua"] = {
|
||||||
|
|
|
@ -283,6 +283,8 @@ if(BUILD_UNITTESTS OR BUILD_BENCHMARKS)
|
||||||
add_subdirectory(lib/catch2)
|
add_subdirectory(lib/catch2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(lib/tiniergltf)
|
||||||
|
|
||||||
# Subdirectories
|
# Subdirectories
|
||||||
# Be sure to add all relevant definitions above this
|
# Be sure to add all relevant definitions above this
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
|
@ -8,7 +8,7 @@ android {
|
||||||
compileSdk 34
|
compileSdk 34
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
|
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
|
||||||
versionCode project.versionCode
|
versionCode versionMajor * 1000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild
|
||||||
}
|
}
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
|
@ -116,18 +116,6 @@ clean {
|
||||||
delete new File("src/main/assets", "Minetest.zip")
|
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 {
|
dependencies {
|
||||||
implementation project(':native')
|
implementation project(':native')
|
||||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
|
|
|
@ -4,10 +4,9 @@ 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
|
project.ext.set("versionPatch", 0) // Version Patch
|
||||||
// ^ keep in sync with cmake
|
// ^ keep in sync with cmake
|
||||||
project.ext.set("versionCode", 48) // Android Version Code
|
|
||||||
// NOTE: +2 after each release!
|
project.ext.set("versionBuild", 0) // Version Build
|
||||||
// +1 for ARM and +1 for ARM64 APK's, because
|
// ^ fourth version number to allow releasing Android-only fixes and beta versions
|
||||||
// each APK must have a larger `versionCode` than the previous
|
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.ndk_version = '26.2.11394342'
|
ext.ndk_version = '26.2.11394342'
|
||||||
|
|
|
@ -69,7 +69,7 @@ local function build_chatcommands_formspec(name, sel, copy)
|
||||||
description = cmds[2].description
|
description = cmds[2].description
|
||||||
if copy then
|
if copy then
|
||||||
local msg = S("Command: @1 @2",
|
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
|
if INIT == "client" then
|
||||||
core.display_chat_message(msg)
|
core.display_chat_message(msg)
|
||||||
else
|
else
|
||||||
|
|
41
builtin/common/math.lua
Normal file
41
builtin/common/math.lua
Normal 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
|
|
@ -3,6 +3,7 @@
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Localize functions to avoid table lookups (better performance).
|
-- Localize functions to avoid table lookups (better performance).
|
||||||
local string_sub, string_find = string.sub, string.find
|
local string_sub, string_find = string.sub, string.find
|
||||||
|
local math = math
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
local function basic_dump(o)
|
local function basic_dump(o)
|
||||||
|
@ -220,47 +221,6 @@ function string:trim()
|
||||||
return self:match("^%s*(.-)%s*$")
|
return self:match("^%s*(.-)%s*$")
|
||||||
end
|
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 = {
|
local formspec_escapes = {
|
||||||
["\\"] = "\\\\",
|
["\\"] = "\\\\",
|
||||||
["["] = "\\[",
|
["["] = "\\[",
|
||||||
|
@ -702,6 +662,7 @@ function core.privs_to_string(privs, delim)
|
||||||
list[#list + 1] = priv
|
list[#list + 1] = priv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
table.sort(list)
|
||||||
return table.concat(list, delim)
|
return table.concat(list, delim)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
_G.core = {}
|
_G.core = {}
|
||||||
_G.vector = {metatable = {}}
|
_G.vector = {metatable = {}}
|
||||||
|
|
||||||
|
dofile("builtin/common/math.lua")
|
||||||
dofile("builtin/common/vector.lua")
|
dofile("builtin/common/vector.lua")
|
||||||
dofile("builtin/common/misc_helpers.lua")
|
dofile("builtin/common/misc_helpers.lua")
|
||||||
|
|
||||||
|
|
16
builtin/common/tests/math_spec.lua
Normal file
16
builtin/common/tests/math_spec.lua
Normal 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)
|
|
@ -1,4 +1,5 @@
|
||||||
_G.core = {}
|
_G.core = {}
|
||||||
|
dofile("builtin/common/math.lua")
|
||||||
dofile("builtin/common/vector.lua")
|
dofile("builtin/common/vector.lua")
|
||||||
dofile("builtin/common/misc_helpers.lua")
|
dofile("builtin/common/misc_helpers.lua")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
_G.vector = {}
|
_G.vector = {}
|
||||||
|
dofile("builtin/common/math.lua")
|
||||||
dofile("builtin/common/vector.lua")
|
dofile("builtin/common/vector.lua")
|
||||||
|
|
||||||
describe("vector", function()
|
describe("vector", function()
|
||||||
|
@ -113,12 +114,35 @@ describe("vector", function()
|
||||||
assert.equal(vector.new(0, 1, -1), a:round())
|
assert.equal(vector.new(0, 1, -1), a:round())
|
||||||
end)
|
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()
|
it("apply()", function()
|
||||||
local i = 0
|
local i = 0
|
||||||
local f = function(x)
|
local f = function(x)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
return x + i
|
return x + i
|
||||||
end
|
end
|
||||||
|
local f2 = function(x, opt1, opt2, opt3)
|
||||||
|
return x + opt1 + opt2 + opt3
|
||||||
|
end
|
||||||
local a = vector.new(0.1, 0.9, -0.5)
|
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), vector.apply(a, math.ceil))
|
||||||
assert.equal(vector.new(1, 1, 0), a:apply(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(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(1.1, 2.9, 2.5), vector.apply(a, f))
|
||||||
assert.equal(vector.new(4.1, 5.9, 5.5), a:apply(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)
|
end)
|
||||||
|
|
||||||
it("combine()", function()
|
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.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)))
|
assert.False(vector.in_area(vector.new(-10, -10, -10), vector.new(10, 10, 10), vector.new(-11, -10, -10)))
|
||||||
end)
|
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)
|
end)
|
||||||
|
|
|
@ -5,6 +5,7 @@ Note: The vector.*-functions must be able to accept old vectors that had no meta
|
||||||
|
|
||||||
-- localize functions
|
-- localize functions
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
|
local math = math
|
||||||
|
|
||||||
vector = {}
|
vector = {}
|
||||||
|
|
||||||
|
@ -97,18 +98,26 @@ function vector.floor(v)
|
||||||
end
|
end
|
||||||
|
|
||||||
function vector.round(v)
|
function vector.round(v)
|
||||||
return fast_new(
|
return vector.apply(v, math.round)
|
||||||
math.round(v.x),
|
|
||||||
math.round(v.y),
|
|
||||||
math.round(v.z)
|
|
||||||
)
|
|
||||||
end
|
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(
|
return fast_new(
|
||||||
func(v.x),
|
func(v.x, ...),
|
||||||
func(v.y),
|
func(v.y, ...),
|
||||||
func(v.z)
|
func(v.z, ...)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -387,6 +396,14 @@ function vector.random_direction()
|
||||||
return fast_new(x/l, y/l, z/l)
|
return fast_new(x/l, y/l, z/l)
|
||||||
end
|
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
|
if rawget(_G, "core") and core.set_read_vector and core.set_push_vector then
|
||||||
local function read_vector(v)
|
local function read_vector(v)
|
||||||
return v.x, v.y, v.z
|
return v.x, v.y, v.z
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
local BASE_SPACING = 0.1
|
local BASE_SPACING = 0.1
|
||||||
local function get_scroll_btn_width()
|
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
|
end
|
||||||
|
|
||||||
local function buttonbar_formspec(self)
|
local function buttonbar_formspec(self)
|
||||||
|
|
|
@ -221,6 +221,7 @@ core.register_chatcommand("haspriv", {
|
||||||
return true, S("No online player has the \"@1\" privilege.",
|
return true, S("No online player has the \"@1\" privilege.",
|
||||||
param)
|
param)
|
||||||
else
|
else
|
||||||
|
table.sort(players_with_priv)
|
||||||
return true, S("Players online with the \"@1\" privilege: @2",
|
return true, S("Players online with the \"@1\" privilege: @2",
|
||||||
param,
|
param,
|
||||||
table.concat(players_with_priv, ", "))
|
table.concat(players_with_priv, ", "))
|
||||||
|
|
|
@ -42,6 +42,7 @@ core.features = {
|
||||||
node_interaction_actor = true,
|
node_interaction_actor = true,
|
||||||
moveresult_new_pos = true,
|
moveresult_new_pos = true,
|
||||||
override_item_remove_fields = true,
|
override_item_remove_fields = true,
|
||||||
|
hotbar_hud_element = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function core.has_feature(arg)
|
function core.has_feature(arg)
|
||||||
|
|
|
@ -251,11 +251,31 @@ register_builtin_hud_element("minimap", {
|
||||||
position = {x = 1, y = 0},
|
position = {x = 1, y = 0},
|
||||||
alignment = {x = -1, y = 1},
|
alignment = {x = -1, y = 1},
|
||||||
offset = {x = -10, y = 10},
|
offset = {x = -10, y = 10},
|
||||||
size = {x = 256, y = 256},
|
size = {x = 0, y = -25},
|
||||||
},
|
},
|
||||||
show_elem = function(player, flags)
|
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++.
|
-- Don't add a minimap for clients which already have it hardcoded in C++.
|
||||||
return flags.minimap and
|
return flags.minimap and proto_ver >= 44
|
||||||
core.get_player_information(player:get_player_name()).protocol_version >= 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,
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -42,6 +42,7 @@ local scriptdir = core.get_builtin_path()
|
||||||
local commonpath = scriptdir .. "common" .. DIR_DELIM
|
local commonpath = scriptdir .. "common" .. DIR_DELIM
|
||||||
local asyncpath = scriptdir .. "async" .. DIR_DELIM
|
local asyncpath = scriptdir .. "async" .. DIR_DELIM
|
||||||
|
|
||||||
|
dofile(commonpath .. "math.lua")
|
||||||
dofile(commonpath .. "vector.lua")
|
dofile(commonpath .. "vector.lua")
|
||||||
dofile(commonpath .. "strict.lua")
|
dofile(commonpath .. "strict.lua")
|
||||||
dofile(commonpath .. "serialize.lua")
|
dofile(commonpath .. "serialize.lua")
|
||||||
|
|
|
@ -181,7 +181,7 @@ local function get_info_formspec(text)
|
||||||
return table.concat({
|
return table.concat({
|
||||||
"formspec_version[6]",
|
"formspec_version[6]",
|
||||||
"size[15.75,9.5]",
|
"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, "]",
|
"label[4,4.35;", text, "]",
|
||||||
"container[0,", H - 0.8 - 0.375, "]",
|
"container[0,", H - 0.8 - 0.375, "]",
|
||||||
|
@ -212,7 +212,7 @@ local function get_formspec(dlgdata)
|
||||||
local formspec = {
|
local formspec = {
|
||||||
"formspec_version[6]",
|
"formspec_version[6]",
|
||||||
"size[15.75,9.5]",
|
"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]",
|
"style[status,downloading,queued;border=false]",
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ end
|
||||||
local function handle_events(event)
|
local function handle_events(event)
|
||||||
if event == "DialogShow" then
|
if event == "DialogShow" then
|
||||||
-- On touchscreen, don't show the "MINETEST" header behind the dialog.
|
-- 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.
|
-- If ContentDB is already loaded, auto-install packages here.
|
||||||
do_auto_install()
|
do_auto_install()
|
||||||
|
|
|
@ -22,13 +22,13 @@ end
|
||||||
|
|
||||||
|
|
||||||
local function get_loading_formspec()
|
local function get_loading_formspec()
|
||||||
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 formspec = {
|
local formspec = {
|
||||||
"formspec_version[3]",
|
"formspec_version[3]",
|
||||||
"size[", w, ",9.05]",
|
"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..."), "]",
|
"label[3,4.525;", fgettext("Loading..."), "]",
|
||||||
}
|
}
|
||||||
return table.concat(formspec)
|
return table.concat(formspec)
|
||||||
|
@ -110,18 +110,18 @@ local function get_formspec(data)
|
||||||
message_bg = mt_color_orange
|
message_bg = mt_color_orange
|
||||||
end
|
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 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_w = (padded_w - 0.25) / 3
|
||||||
local button_pad = button_w / 2
|
local button_pad = button_w / 2
|
||||||
|
|
||||||
local formspec = {
|
local formspec = {
|
||||||
"formspec_version[3]",
|
"formspec_version[3]",
|
||||||
"size[", w, ",9.05]",
|
"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]",
|
"style[title;border=false]",
|
||||||
"box[0,0;", w, ",0.8;#3333]",
|
"box[0,0;", w, ",0.8;#3333]",
|
||||||
"button[0,0;", w, ",0.8;title;", fgettext("Install $1", package.title) , "]",
|
"button[0,0;", w, ",0.8;title;", fgettext("Install $1", package.title) , "]",
|
||||||
|
|
85
builtin/mainmenu/credits.json
Normal file
85
builtin/mainmenu/credits.json
Normal 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>"
|
||||||
|
]
|
||||||
|
}
|
|
@ -126,7 +126,7 @@ local function get_formspec(data)
|
||||||
local retval =
|
local retval =
|
||||||
"size[11.5,7.5,true]" ..
|
"size[11.5,7.5,true]" ..
|
||||||
"label[0.5,0;" .. fgettext("World:") .. "]" ..
|
"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
|
if mod.is_modpack or mod.type == "game" then
|
||||||
local info = core.formspec_escape(
|
local info = core.formspec_escape(
|
||||||
|
|
|
@ -110,7 +110,7 @@ local function load()
|
||||||
local change_keys = {
|
local change_keys = {
|
||||||
query_text = "Controls",
|
query_text = "Controls",
|
||||||
requires = {
|
requires = {
|
||||||
keyboard_mouse = true,
|
touch_controls = false,
|
||||||
},
|
},
|
||||||
get_formspec = function(self, avail_w)
|
get_formspec = function(self, avail_w)
|
||||||
local btn_w = math.min(avail_w, 3)
|
local btn_w = math.min(avail_w, 3)
|
||||||
|
@ -324,8 +324,6 @@ local function check_requirements(name, requires)
|
||||||
local special = {
|
local special = {
|
||||||
android = PLATFORM == "Android",
|
android = PLATFORM == "Android",
|
||||||
desktop = 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_support = shaders_support,
|
||||||
shaders = core.settings:get_bool("enable_shaders") and shaders_support,
|
shaders = core.settings:get_bool("enable_shaders") and shaders_support,
|
||||||
opengl = video_driver == "opengl",
|
opengl = video_driver == "opengl",
|
||||||
|
@ -457,13 +455,13 @@ local function get_formspec(dialogdata)
|
||||||
|
|
||||||
local extra_h = 1 -- not included in tabsize.height
|
local extra_h = 1 -- not included in tabsize.height
|
||||||
local tabsize = {
|
local tabsize = {
|
||||||
width = core.settings:get_bool("enable_touch") and 16.5 or 15.5,
|
width = core.settings:get_bool("touch_gui") and 16.5 or 15.5,
|
||||||
height = core.settings:get_bool("enable_touch") and (10 - extra_h) or 12,
|
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 left_pane_padding = 0.25
|
||||||
local search_width = left_pane_width + scrollbar_w - (0.75 * 2)
|
local search_width = left_pane_width + scrollbar_w - (0.75 * 2)
|
||||||
|
|
||||||
|
@ -477,7 +475,7 @@ local function get_formspec(dialogdata)
|
||||||
local fs = {
|
local fs = {
|
||||||
"formspec_version[6]",
|
"formspec_version[6]",
|
||||||
"size[", tostring(tabsize.width), ",", tostring(tabsize.height + extra_h), "]",
|
"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]",
|
"bgcolor[#0000]",
|
||||||
|
|
||||||
-- HACK: this is needed to allow resubmitting the same formspec
|
-- HACK: this is needed to allow resubmitting the same formspec
|
||||||
|
@ -652,15 +650,15 @@ local function buttonhandler(this, fields)
|
||||||
write_settings_early()
|
write_settings_early()
|
||||||
end
|
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
|
-- setting differently so we can hide/show pages using the next if-statement
|
||||||
if fields.enable_touch ~= nil then
|
if fields.touch_controls ~= nil then
|
||||||
local value = core.is_yes(fields.enable_touch)
|
local value = core.is_yes(fields.touch_controls)
|
||||||
core.settings:set_bool("enable_touch", value)
|
core.settings:set_bool("touch_controls", value)
|
||||||
write_settings_early()
|
write_settings_early()
|
||||||
end
|
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)
|
local suggested_page_id = update_filtered_pages(dialogdata.query)
|
||||||
|
|
||||||
dialogdata.components = nil
|
dialogdata.components = nil
|
||||||
|
|
|
@ -15,96 +15,6 @@
|
||||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
--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 function prepare_credits(dest, source)
|
||||||
local string = table.concat(source, "\n") .. "\n"
|
local string = table.concat(source, "\n") .. "\n"
|
||||||
|
@ -120,6 +30,13 @@ local function prepare_credits(dest, source)
|
||||||
table.insert(dest, string)
|
table.insert(dest, string)
|
||||||
end
|
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 {
|
return {
|
||||||
name = "about",
|
name = "about",
|
||||||
caption = fgettext("About"),
|
caption = fgettext("About"),
|
||||||
|
@ -133,30 +50,32 @@ return {
|
||||||
"<tag name=gray color=#aaa>",
|
"<tag name=gray color=#aaa>",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local credits = get_credits()
|
||||||
|
|
||||||
table.insert_all(hypertext, {
|
table.insert_all(hypertext, {
|
||||||
"<heading>", fgettext_ne("Core Developers"), "</heading>\n",
|
"<heading>", fgettext_ne("Core Developers"), "</heading>\n",
|
||||||
})
|
})
|
||||||
prepare_credits(hypertext, core_developers)
|
prepare_credits(hypertext, credits.core_developers)
|
||||||
table.insert_all(hypertext, {
|
table.insert_all(hypertext, {
|
||||||
"\n",
|
"\n",
|
||||||
"<heading>", fgettext_ne("Core Team"), "</heading>\n",
|
"<heading>", fgettext_ne("Core Team"), "</heading>\n",
|
||||||
})
|
})
|
||||||
prepare_credits(hypertext, core_team)
|
prepare_credits(hypertext, credits.core_team)
|
||||||
table.insert_all(hypertext, {
|
table.insert_all(hypertext, {
|
||||||
"\n",
|
"\n",
|
||||||
"<heading>", fgettext_ne("Active Contributors"), "</heading>\n",
|
"<heading>", fgettext_ne("Active Contributors"), "</heading>\n",
|
||||||
})
|
})
|
||||||
prepare_credits(hypertext, active_contributors)
|
prepare_credits(hypertext, credits.contributors)
|
||||||
table.insert_all(hypertext, {
|
table.insert_all(hypertext, {
|
||||||
"\n",
|
"\n",
|
||||||
"<heading>", fgettext_ne("Previous Core Developers"), "</heading>\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, {
|
table.insert_all(hypertext, {
|
||||||
"\n",
|
"\n",
|
||||||
"<heading>", fgettext_ne("Previous Contributors"), "</heading>\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)
|
hypertext = table.concat(hypertext):sub(1, -2)
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ function singleplayer_refresh_gamebar()
|
||||||
|
|
||||||
local btnbar = buttonbar_create(
|
local btnbar = buttonbar_create(
|
||||||
"game_button_bar",
|
"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},
|
{x = 15.5, y = 1.25},
|
||||||
"#000000",
|
"#000000",
|
||||||
game_buttonbar_button_handler)
|
game_buttonbar_button_handler)
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
#
|
#
|
||||||
# # This is a comment
|
# # This is a comment
|
||||||
# #
|
# #
|
||||||
# # Requires: shaders, enable_dynamic_shadows, !touchscreen_gui
|
# # Requires: shaders, enable_dynamic_shadows, !touch_controls
|
||||||
# name (Readable name) type type_args
|
# name (Readable name) type type_args
|
||||||
#
|
#
|
||||||
# A requirement can be the name of a boolean setting or an engine-defined value.
|
# 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_support (a video driver that supports shaders, may not be enabled)
|
||||||
# * shaders (both enable_shaders and shaders_support)
|
# * shaders (both enable_shaders and shaders_support)
|
||||||
# * desktop / android
|
# * desktop / android
|
||||||
# * touchscreen_gui / keyboard_mouse
|
|
||||||
# * opengl / gles
|
# * opengl / gles
|
||||||
# * You can negate any requirement by prepending with !
|
# * 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.
|
# 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
|
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.
|
# 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 time in seconds it takes between repeated node placements when holding
|
||||||
# the place button.
|
# the place button.
|
||||||
#
|
#
|
||||||
# Requires: keyboard_mouse
|
# Requires: !touch_controls
|
||||||
repeat_place_time (Place repetition interval) float 0.25 0.16 2.0
|
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
|
# 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.
|
# Invert vertical mouse movement.
|
||||||
#
|
#
|
||||||
# Requires: keyboard_mouse
|
# Requires: !touch_controls
|
||||||
invert_mouse (Invert mouse) bool false
|
invert_mouse (Invert mouse) bool false
|
||||||
|
|
||||||
# Mouse sensitivity multiplier.
|
# Mouse sensitivity multiplier.
|
||||||
#
|
#
|
||||||
# Requires: keyboard_mouse
|
# Requires: !touch_controls
|
||||||
mouse_sensitivity (Mouse sensitivity) float 0.2 0.001 10.0
|
mouse_sensitivity (Mouse sensitivity) float 0.2 0.001 10.0
|
||||||
|
|
||||||
# Enable mouse wheel (scroll) for item selection in hotbar.
|
# 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
|
enable_hotbar_mouse_wheel (Hotbar: Enable mouse wheel for selection) bool true
|
||||||
|
|
||||||
# Invert mouse wheel (scroll) direction for item selection in hotbar.
|
# 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
|
invert_hotbar_mouse_wheel (Hotbar: Invert mouse wheel direction) bool false
|
||||||
|
|
||||||
[*Touchscreen]
|
[*Touchscreen]
|
||||||
|
|
||||||
# Enables touchscreen mode, allowing you to play the game with a touchscreen.
|
# Enables the touchscreen controls, allowing you to play the game with a touchscreen.
|
||||||
#
|
touch_controls (Enable touchscreen controls) bool true
|
||||||
# Requires: !android
|
|
||||||
enable_touch (Enable touchscreen) bool true
|
|
||||||
|
|
||||||
# Touchscreen sensitivity multiplier.
|
# Touchscreen sensitivity multiplier.
|
||||||
#
|
#
|
||||||
# Requires: touchscreen_gui
|
# Requires: touch_controls
|
||||||
touchscreen_sensitivity (Touchscreen sensitivity) float 0.2 0.001 10.0
|
touchscreen_sensitivity (Touchscreen sensitivity) float 0.2 0.001 10.0
|
||||||
|
|
||||||
# The length in pixels after which a touch interaction is considered movement.
|
# 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
|
touchscreen_threshold (Movement threshold) int 20 0 100
|
||||||
|
|
||||||
# The delay in milliseconds after which a touch interaction is considered a long tap.
|
# 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
|
touch_long_tap_delay (Threshold for long taps) int 400 100 1000
|
||||||
|
|
||||||
# Use crosshair to select object instead of whole screen.
|
# Use crosshair to select object instead of whole screen.
|
||||||
# If enabled, a crosshair will be shown and will be used for selecting object.
|
# 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
|
touch_use_crosshair (Use crosshair for touch screen) bool false
|
||||||
|
|
||||||
# Fixes the position of virtual joystick.
|
# Fixes the position of virtual joystick.
|
||||||
# If disabled, virtual joystick will center to first-touch's position.
|
# 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
|
fixed_virtual_joystick (Fixed virtual joystick) bool false
|
||||||
|
|
||||||
# Use virtual joystick to trigger "Aux1" button.
|
# Use virtual joystick to trigger "Aux1" button.
|
||||||
# If enabled, virtual joystick will also tap "Aux1" button when out of main circle.
|
# 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
|
virtual_joystick_triggers_aux1 (Virtual joystick triggers Aux1 button) bool false
|
||||||
|
|
||||||
# The gesture for punching players/entities.
|
# 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.
|
# Known from the classic Minetest mobile controls.
|
||||||
# Combat is more or less impossible.
|
# Combat is more or less impossible.
|
||||||
#
|
#
|
||||||
# Requires: touchscreen_gui
|
# Requires: touch_controls
|
||||||
touch_punch_gesture (Punch gesture) enum short_tap short_tap,long_tap
|
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]
|
[**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.
|
# Scale GUI by a user specified value.
|
||||||
# Use a nearest-neighbor-anti-alias filter to scale the GUI.
|
# Use a nearest-neighbor-anti-alias filter to scale the GUI.
|
||||||
# This will smooth over some of the rough edges, and blend
|
# 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.
|
# Mods may still set a background.
|
||||||
show_nametag_backgrounds (Show name tag backgrounds by default) bool true
|
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]
|
[**Chat]
|
||||||
|
|
||||||
# Maximum number of recent chat messages to show
|
# Maximum number of recent chat messages to show
|
||||||
|
@ -1848,11 +1855,11 @@ shader_path (Shader path) path
|
||||||
# The rendering back-end.
|
# The rendering back-end.
|
||||||
# Note: A restart is required after changing this!
|
# Note: A restart is required after changing this!
|
||||||
# OpenGL is the default for desktop, and OGLES2 for Android.
|
# OpenGL is the default for desktop, and OGLES2 for Android.
|
||||||
# Shaders are supported by everything but OGLES1.
|
video_driver (Video driver) enum ,opengl,opengl3,ogles2
|
||||||
video_driver (Video driver) enum ,opengl,opengl3,ogles1,ogles2
|
|
||||||
|
|
||||||
# Distance in nodes at which transparency depth sorting is enabled
|
# Distance in nodes at which transparency depth sorting is enabled.
|
||||||
# Use this to limit the performance impact of transparency depth sorting
|
# 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
|
transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
|
||||||
|
|
||||||
# Radius of cloud area stated in number of 64 node cloud squares.
|
# 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.
|
# Set to -1 for unlimited amount.
|
||||||
client_mapblock_limit (Mapblock limit) int 7500 -1 2147483647
|
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.
|
# Maximum number of blocks that are simultaneously sent per client.
|
||||||
# The maximum total count is calculated dynamically:
|
# The maximum total count is calculated dynamically:
|
||||||
# max_total = ceil((#clients + max_users) * per_client / 4)
|
# 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.
|
# 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
|
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
|
# Maximum number of packets sent per send step in the low-level networking code.
|
||||||
# try reducing it, but don't reduce it to a number below double of targeted
|
# You generally don't need to change this, however busy servers may benefit from a higher number.
|
||||||
# client number.
|
|
||||||
max_packets_per_iteration (Max. packets per iteration) int 1024 1 65535
|
max_packets_per_iteration (Max. packets per iteration) int 1024 1 65535
|
||||||
|
|
||||||
# Compression level to use when sending mapblocks to the client.
|
# Compression level to use when sending mapblocks to the client.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../../irr/media/Shaders
|
|
|
@ -11,7 +11,7 @@ if(ENABLE_LUAJIT)
|
||||||
find_package(LuaJIT)
|
find_package(LuaJIT)
|
||||||
if(LUAJIT_FOUND)
|
if(LUAJIT_FOUND)
|
||||||
set(USE_LUAJIT TRUE)
|
set(USE_LUAJIT TRUE)
|
||||||
message (STATUS "Using LuaJIT provided by system.")
|
message (STATUS "Using LuaJIT")
|
||||||
elseif(REQUIRE_LUAJIT)
|
elseif(REQUIRE_LUAJIT)
|
||||||
message(FATAL_ERROR "LuaJIT not found whereas REQUIRE_LUAJIT=\"TRUE\" is used.\n"
|
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\".")
|
"To continue, either install LuaJIT or do not use REQUIRE_LUAJIT=\"TRUE\".")
|
||||||
|
|
|
@ -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:
|
After you successfully built vcpkg you can easily install the required libraries:
|
||||||
```powershell
|
```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.
|
- `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:
|
Run the following script in PowerShell:
|
||||||
|
|
||||||
```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
|
cmake --build . --config Release
|
||||||
```
|
```
|
||||||
Make sure that the right compiler is selected and the path to the vcpkg toolchain is correct.
|
Make sure that the right compiler is selected and the path to the vcpkg toolchain is correct.
|
||||||
|
|
|
@ -274,7 +274,7 @@ Accepted formats are:
|
||||||
|
|
||||||
images: .png, .jpg, .tga, (deprecated:) .bmp
|
images: .png, .jpg, .tga, (deprecated:) .bmp
|
||||||
sounds: .ogg vorbis
|
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
|
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)
|
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
|
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.
|
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
|
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.
|
* `item`: Position of item that is selected.
|
||||||
* `direction`: Direction the list will be displayed in
|
* `direction`: Direction the list will be displayed in
|
||||||
* `offset`: offset in pixels from position.
|
* `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`
|
### `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
|
* `size`: Size of the minimap to display. Minimap should be a square to avoid
|
||||||
distortion.
|
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.
|
* `alignment`: The alignment of the minimap.
|
||||||
* `offset`: offset in pixels from position.
|
* `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
|
**WARNING**: do _not_ use an element name starting with `key_`; those names are
|
||||||
reserved to pass key press events to formspec!
|
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
|
**WARNING**: Minetest allows you to add elements to every single formspec instance
|
||||||
using `player:set_formspec_prepend()`, which may be the reason backgrounds are
|
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
|
appearing when you don't expect them to, or why things are styled differently
|
||||||
|
@ -2861,14 +2913,14 @@ Elements
|
||||||
* Requires formspec version >= 6.
|
* Requires formspec version >= 6.
|
||||||
* See `background9[]` documentation for more information.
|
* 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.
|
* Show a mesh model.
|
||||||
* `name`: Element name that can be used for styling
|
* `name`: Element name that can be used for styling
|
||||||
* `mesh`: The mesh model to use.
|
* `mesh`: The mesh model to use.
|
||||||
* `textures`: The mesh textures to use according to the mesh materials.
|
* `textures`: The mesh textures to use according to the mesh materials.
|
||||||
Texture names must be separated by commas.
|
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.
|
The axes are euler angles in degrees.
|
||||||
* `continuous` (Optional): Whether the rotation is continuous. Default `false`.
|
* `continuous` (Optional): Whether the rotation is continuous. Default `false`.
|
||||||
* `mouse control` (Optional): Whether the model can be controlled with the mouse. Default `true`.
|
* `mouse control` (Optional): Whether the model can be controlled with the mouse. Default `true`.
|
||||||
|
@ -3847,12 +3899,20 @@ vectors are written like this: `(x, y, z)`:
|
||||||
* If `v` has zero length, returns `(0, 0, 0)`.
|
* If `v` has zero length, returns `(0, 0, 0)`.
|
||||||
* `vector.floor(v)`:
|
* `vector.floor(v)`:
|
||||||
* Returns a vector, each dimension rounded down.
|
* Returns a vector, each dimension rounded down.
|
||||||
|
* `vector.ceil(v)`:
|
||||||
|
* Returns a vector, each dimension rounded up.
|
||||||
* `vector.round(v)`:
|
* `vector.round(v)`:
|
||||||
* Returns a vector, each dimension rounded to nearest integer.
|
* Returns a vector, each dimension rounded to nearest integer.
|
||||||
* At a multiple of 0.5, rounds away from zero.
|
* 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
|
* Returns a vector where the function `func` has been applied to each
|
||||||
component.
|
component.
|
||||||
|
* `...` are optional arguments passed to `func`.
|
||||||
* `vector.combine(v, w, func)`:
|
* `vector.combine(v, w, func)`:
|
||||||
* Returns a vector where the function `func` has combined both components of `v` and `w`
|
* Returns a vector where the function `func` has combined both components of `v` and `w`
|
||||||
for each component
|
for each component
|
||||||
|
@ -3877,6 +3937,10 @@ vectors are written like this: `(x, y, z)`:
|
||||||
* `min` and `max` are inclusive.
|
* `min` and `max` are inclusive.
|
||||||
* If `min` is bigger than `max` on some axis, function always returns false.
|
* 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.
|
* 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:
|
For the following functions `x` can be either a vector or a number:
|
||||||
|
|
||||||
|
@ -5456,6 +5520,8 @@ Utilities
|
||||||
moveresult_new_pos = true,
|
moveresult_new_pos = true,
|
||||||
-- Allow removing definition fields in `minetest.override_item` (5.9.0)
|
-- Allow removing definition fields in `minetest.override_item` (5.9.0)
|
||||||
override_item_remove_fields = true,
|
override_item_remove_fields = true,
|
||||||
|
-- The predefined hotbar is a Lua HUD element of type `hotbar` (5.10.0)
|
||||||
|
hotbar_hud_element = true,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -6463,7 +6529,8 @@ Formspec
|
||||||
* `playername`: name of player to show formspec
|
* `playername`: name of player to show formspec
|
||||||
* `formname`: name passed to `on_player_receive_fields` callbacks.
|
* `formname`: name passed to `on_player_receive_fields` callbacks.
|
||||||
It should follow the `"modname:<whatever>"` naming convention.
|
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
|
* `formspec`: formspec to display
|
||||||
* `minetest.close_formspec(playername, formname)`
|
* `minetest.close_formspec(playername, formname)`
|
||||||
* `playername`: name of player to close formspec
|
* `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).
|
could be used as a player name (regardless of whether said player exists).
|
||||||
* `minetest.hud_replace_builtin(name, hud_definition)`
|
* `minetest.hud_replace_builtin(name, hud_definition)`
|
||||||
* Replaces definition of a builtin hud element
|
* 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
|
* `hud_definition`: definition to replace builtin definition
|
||||||
* `minetest.parse_relative_number(arg, relative_to)`: returns number or nil
|
* `minetest.parse_relative_number(arg, relative_to)`: returns number or nil
|
||||||
* Helper function for chat commands.
|
* Helper function for chat commands.
|
||||||
|
@ -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`.
|
* 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,
|
* `respawn()`: Respawns the player using the same mechanism as the death screen,
|
||||||
including calling `on_respawnplayer` callbacks.
|
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`
|
`PcgRandom`
|
||||||
-----------
|
-----------
|
||||||
|
@ -8669,7 +8744,7 @@ In multiplayer mode, the error may be arbitrarily large.
|
||||||
|
|
||||||
Interface for the operating system's crypto-secure PRNG.
|
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.
|
secure random device cannot be found on the system.
|
||||||
|
|
||||||
### Methods
|
### Methods
|
||||||
|
@ -10640,8 +10715,9 @@ Used by `ObjectRef:hud_add`. Returned by `ObjectRef:hud_get`.
|
||||||
```lua
|
```lua
|
||||||
{
|
{
|
||||||
type = "image",
|
type = "image",
|
||||||
-- Type of element, can be "image", "text", "statbar", "inventory",
|
-- Type of element, can be "compass", "hotbar" (46 ¹), "image", "image_waypoint",
|
||||||
-- "waypoint", "image_waypoint", "compass" or "minimap"
|
-- "inventory", "minimap" (44 ¹), "statbar", "text" or "waypoint"
|
||||||
|
-- ¹: minimal protocol version for client-side support
|
||||||
-- If undefined "text" will be used.
|
-- If undefined "text" will be used.
|
||||||
|
|
||||||
hud_elem_type = "image",
|
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
|
* vec3 range `acc`: the direction and speed with which the particle
|
||||||
accelerates
|
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
|
if `node` is set, this can be set to 0 to spawn randomly-sized particles
|
||||||
(just like actual node dig particles).
|
(just like actual node dig particles).
|
||||||
|
|
||||||
|
|
|
@ -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`
|
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
|
Callbacks
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -62,6 +71,12 @@ Functions
|
||||||
Filesystem
|
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()`
|
* `core.get_builtin_path()`
|
||||||
* returns path to builtin root
|
* returns path to builtin root
|
||||||
* `core.create_dir(absolute_path)` (possible in async calls)
|
* `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
|
```lua
|
||||||
{
|
{
|
||||||
mods = "/home/user/.minetest/mods",
|
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
|
-- Custom dirs can be specified by the MINETEST_MOD_DIR env variable
|
||||||
["/path/to/custom/dir"] = "/path/to/custom/dir",
|
["/path/to/custom/dir"] = "/path/to/custom/dir",
|
||||||
|
|
14
games/devtest/mods/gltf/LICENSE.md
Normal file
14
games/devtest/mods/gltf/LICENSE.md
Normal 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
|
51
games/devtest/mods/gltf/init.lua
Normal file
51
games/devtest/mods/gltf/init.lua
Normal 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,
|
||||||
|
})
|
0
games/devtest/mods/gltf/invalid/empty.gltf
Normal file
0
games/devtest/mods/gltf/invalid/empty.gltf
Normal 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"}}
|
1
games/devtest/mods/gltf/invalid/json_missing_brace.gltf
Normal file
1
games/devtest/mods/gltf/invalid/json_missing_brace.gltf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{
|
2
games/devtest/mods/gltf/mod.conf
Normal file
2
games/devtest/mods/gltf/mod.conf
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
name = gltf
|
||||||
|
description = Hosts gltf test models, both for the C++ unit tests and for in-game viewing
|
1
games/devtest/mods/gltf/models/gltf_blender_cube.gltf
Normal file
1
games/devtest/mods/gltf/models/gltf_blender_cube.gltf
Normal 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"}]}
|
|
@ -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"}]}
|
|
@ -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"}]}
|
1
games/devtest/mods/gltf/models/gltf_frog.gltf
Normal file
1
games/devtest/mods/gltf/models/gltf_frog.gltf
Normal file
File diff suppressed because one or more lines are too long
|
@ -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"}}
|
|
@ -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"}}
|
1
games/devtest/mods/gltf/models/gltf_snow_man.gltf
Normal file
1
games/devtest/mods/gltf/models/gltf_snow_man.gltf
Normal file
File diff suppressed because one or more lines are too long
1
games/devtest/mods/gltf/models/gltf_spider.gltf
Normal file
1
games/devtest/mods/gltf/models/gltf_spider.gltf
Normal file
File diff suppressed because one or more lines are too long
|
@ -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"}}
|
|
@ -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"}}
|
BIN
games/devtest/mods/gltf/textures/gltf_cube.png
Normal file
BIN
games/devtest/mods/gltf/textures/gltf_cube.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 203 B |
BIN
games/devtest/mods/gltf/textures/gltf_frog.png
Normal file
BIN
games/devtest/mods/gltf/textures/gltf_frog.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 272 B |
BIN
games/devtest/mods/gltf/textures/gltf_snow_man.png
Normal file
BIN
games/devtest/mods/gltf/textures/gltf_snow_man.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 205 B |
BIN
games/devtest/mods/gltf/textures/gltf_spider.png
Normal file
BIN
games/devtest/mods/gltf/textures/gltf_spider.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -208,9 +208,75 @@ minetest.register_chatcommand("zoomfov", {
|
||||||
end,
|
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)
|
minetest.register_on_leaveplayer(function(player)
|
||||||
player_font_huds[player:get_player_name()] = nil
|
player_font_huds[player:get_player_name()] = nil
|
||||||
player_waypoints[player:get_player_name()] = nil
|
player_waypoints[player:get_player_name()] = nil
|
||||||
|
player_hud_hotbars[player:get_player_name()] = nil
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_chatcommand("hudprint", {
|
minetest.register_chatcommand("hudprint", {
|
||||||
|
@ -232,3 +298,26 @@ minetest.register_chatcommand("hudprint", {
|
||||||
return true, s
|
return true, s
|
||||||
end
|
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
|
||||||
|
})
|
||||||
|
|
|
@ -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))
|
return core.objects_in_area(pos:offset(-1, -1, -1), pos:offset(1, 1, 1))
|
||||||
end)
|
end)
|
||||||
end, {map=true})
|
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})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
-- HP Change Reasons
|
-- HP Change Reasons
|
||||||
--
|
--
|
||||||
local expect = nil
|
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
|
if expect == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -37,6 +37,48 @@ local function run_hpchangereason_tests(player)
|
||||||
end
|
end
|
||||||
unittests.register("test_hpchangereason", run_hpchangereason_tests, {player=true})
|
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
|
-- Player meta
|
||||||
--
|
--
|
||||||
|
|
310
irr/.github/workflows/build.yml
vendored
310
irr/.github/workflows/build.yml
vendored
|
@ -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 }}
|
|
|
@ -11,14 +11,5 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type: Debug or Release" FORCE)
|
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type: Debug or Release" FORCE)
|
||||||
endif()
|
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")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
#enable_testing()
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
#add_subdirectory(test)
|
|
||||||
|
|
||||||
#option(BUILD_EXAMPLES "Build example applications" FALSE)
|
|
||||||
#if(BUILD_EXAMPLES)
|
|
||||||
# add_subdirectory(examples)
|
|
||||||
#endif()
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ The following libraries are required to be installed:
|
||||||
Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the following options are available:
|
Aside from standard search options (`ZLIB_INCLUDE_DIR`, `ZLIB_LIBRARY`, ...) the following options are available:
|
||||||
* `ENABLE_OPENGL` - Enable OpenGL driver
|
* `ENABLE_OPENGL` - Enable OpenGL driver
|
||||||
* `ENABLE_OPENGL3` (default: `OFF`) - Enable OpenGL 3+ driver
|
* `ENABLE_OPENGL3` (default: `OFF`) - Enable OpenGL 3+ driver
|
||||||
* `ENABLE_GLES1` - Enable OpenGL ES driver, legacy
|
|
||||||
* `ENABLE_GLES2` - Enable OpenGL ES 2+ driver
|
* `ENABLE_GLES2` - Enable OpenGL ES 2+ driver
|
||||||
* `USE_SDL2` (default: platform-dependent, usually `ON`) - Use SDL2 instead of older native device code
|
* `USE_SDL2` (default: platform-dependent, usually `ON`) - Use SDL2 instead of older native device code
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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)
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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()
|
|
89
irr/include/CIndexBuffer.h
Normal file
89
irr/include/CIndexBuffer.h
Normal 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
|
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "irrArray.h"
|
#include <vector>
|
||||||
#include "IMeshBuffer.h"
|
#include "IMeshBuffer.h"
|
||||||
|
#include "CVertexBuffer.h"
|
||||||
|
#include "CIndexBuffer.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
@ -13,16 +15,24 @@ namespace scene
|
||||||
{
|
{
|
||||||
//! Template implementation of the IMeshBuffer interface
|
//! Template implementation of the IMeshBuffer interface
|
||||||
template <class T>
|
template <class T>
|
||||||
class CMeshBuffer : public IMeshBuffer
|
class CMeshBuffer final : public IMeshBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Default constructor for empty meshbuffer
|
//! Default constructor for empty meshbuffer
|
||||||
CMeshBuffer() :
|
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
|
#ifdef _DEBUG
|
||||||
setDebugName("CMeshBuffer");
|
setDebugName("CMeshBuffer");
|
||||||
#endif
|
#endif
|
||||||
|
Vertices = new CVertexBuffer<T>();
|
||||||
|
Indices = new SIndexBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
~CMeshBuffer()
|
||||||
|
{
|
||||||
|
Vertices->drop();
|
||||||
|
Indices->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get material of this meshbuffer
|
//! Get material of this meshbuffer
|
||||||
|
@ -39,53 +49,24 @@ public:
|
||||||
return Material;
|
return Material;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get pointer to vertices
|
const scene::IVertexBuffer *getVertexBuffer() const override
|
||||||
/** \return Pointer to vertices. */
|
|
||||||
const void *getVertices() const override
|
|
||||||
{
|
{
|
||||||
return Vertices.const_pointer();
|
return Vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get pointer to vertices
|
scene::IVertexBuffer *getVertexBuffer() override
|
||||||
/** \return Pointer to vertices. */
|
|
||||||
void *getVertices() override
|
|
||||||
{
|
{
|
||||||
return Vertices.pointer();
|
return Vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get number of vertices
|
const scene::IIndexBuffer *getIndexBuffer() const override
|
||||||
/** \return Number of vertices. */
|
|
||||||
u32 getVertexCount() const override
|
|
||||||
{
|
{
|
||||||
return Vertices.size();
|
return Indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get type of index data which is stored in this meshbuffer.
|
scene::IIndexBuffer *getIndexBuffer() override
|
||||||
/** \return Index type of this buffer. */
|
|
||||||
video::E_INDEX_TYPE getIndexType() const override
|
|
||||||
{
|
{
|
||||||
return video::EIT_16BIT;
|
return Indices;
|
||||||
}
|
|
||||||
|
|
||||||
//! 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get the axis aligned bounding box
|
//! Get the axis aligned bounding box
|
||||||
|
@ -107,104 +88,36 @@ public:
|
||||||
/** should be called if the mesh changed. */
|
/** should be called if the mesh changed. */
|
||||||
void recalculateBoundingBox() override
|
void recalculateBoundingBox() override
|
||||||
{
|
{
|
||||||
if (!Vertices.empty()) {
|
if (Vertices->getCount()) {
|
||||||
BoundingBox.reset(Vertices[0].Pos);
|
BoundingBox.reset(Vertices->getPosition(0));
|
||||||
const irr::u32 vsize = Vertices.size();
|
const irr::u32 vsize = Vertices->getCount();
|
||||||
for (u32 i = 1; i < vsize; ++i)
|
for (u32 i = 1; i < vsize; ++i)
|
||||||
BoundingBox.addInternalPoint(Vertices[i].Pos);
|
BoundingBox.addInternalPoint(Vertices->getPosition(i));
|
||||||
} else
|
} else
|
||||||
BoundingBox.reset(0, 0, 0);
|
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
|
//! 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
|
void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) override
|
||||||
{
|
{
|
||||||
if (vertices == getVertices())
|
if (vertices == getVertices())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const u32 vertexCount = getVertexCount();
|
const u32 vertexCount = getVertexCount();
|
||||||
u32 i;
|
const u32 indexCount = getIndexCount();
|
||||||
|
|
||||||
Vertices.reallocate(vertexCount + numVertices);
|
auto *vt = static_cast<const T *>(vertices);
|
||||||
for (i = 0; i < numVertices; ++i) {
|
Vertices->Data.insert(Vertices->Data.end(), vt, vt + numVertices);
|
||||||
Vertices.push_back(static_cast<const T *>(vertices)[i]);
|
for (u32 i = vertexCount; i < getVertexCount(); i++)
|
||||||
BoundingBox.addInternalPoint(static_cast<const T *>(vertices)[i].Pos);
|
BoundingBox.addInternalPoint(Vertices->getPosition(i));
|
||||||
}
|
|
||||||
|
|
||||||
Indices.reallocate(getIndexCount() + numIndices);
|
Indices->Data.insert(Indices->Data.end(), indices, indices + numIndices);
|
||||||
for (i = 0; i < numIndices; ++i) {
|
if (vertexCount != 0) {
|
||||||
Indices.push_back(indices[i] + vertexCount);
|
for (u32 i = indexCount; i < getIndexCount(); i++)
|
||||||
|
Indices->Data[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
|
//! Describe what kind of primitive geometry is used by the meshbuffer
|
||||||
void setPrimitiveType(E_PRIMITIVE_TYPE type) override
|
void setPrimitiveType(E_PRIMITIVE_TYPE type) override
|
||||||
{
|
{
|
||||||
|
@ -217,47 +130,12 @@ public:
|
||||||
return PrimitiveType;
|
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.
|
//! Material for this meshbuffer.
|
||||||
video::SMaterial Material;
|
video::SMaterial Material;
|
||||||
//! Vertices of this buffer
|
//! Vertex buffer
|
||||||
core::array<T> Vertices;
|
CVertexBuffer<T> *Vertices;
|
||||||
//! Indices into the vertices of this buffer.
|
//! Index buffer
|
||||||
core::array<u16> Indices;
|
SIndexBuffer *Indices;
|
||||||
//! Bounding box of this meshbuffer.
|
//! Bounding box of this meshbuffer.
|
||||||
core::aabbox3d<f32> BoundingBox;
|
core::aabbox3d<f32> BoundingBox;
|
||||||
//! Primitive type used for rendering (triangles, lines, ...)
|
//! Primitive type used for rendering (triangles, lines, ...)
|
||||||
|
|
122
irr/include/CVertexBuffer.h
Normal file
122
irr/include/CVertexBuffer.h
Normal 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
|
|
@ -24,9 +24,6 @@ enum E_DRIVER_TYPE
|
||||||
primitives. */
|
primitives. */
|
||||||
EDT_OPENGL,
|
EDT_OPENGL,
|
||||||
|
|
||||||
//! OpenGL-ES 1.x driver, for embedded and mobile systems
|
|
||||||
EDT_OGLES1,
|
|
||||||
|
|
||||||
//! OpenGL-ES 2.x driver, for embedded and mobile systems
|
//! OpenGL-ES 2.x driver, for embedded and mobile systems
|
||||||
/** Supports shaders etc. */
|
/** Supports shaders etc. */
|
||||||
EDT_OGLES2,
|
EDT_OGLES2,
|
||||||
|
|
75
irr/include/EVideoTypes.h
Normal file
75
irr/include/EVideoTypes.h
Normal 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
|
||||||
|
|
|
@ -23,27 +23,13 @@ namespace io
|
||||||
class IAttributes : public virtual IReferenceCounted
|
class IAttributes : public virtual IReferenceCounted
|
||||||
{
|
{
|
||||||
public:
|
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
|
//! Returns the type of an attribute
|
||||||
//! \param attributeName: Name for the attribute
|
//! \param attributeName: Name for the attribute
|
||||||
virtual E_ATTRIBUTE_TYPE getAttributeType(const c8 *attributeName) const = 0;
|
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
|
//! Returns if an attribute with a name exists
|
||||||
virtual bool existsAttribute(const c8 *attributeName) const = 0;
|
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
|
//! Removes all attributes
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
|
|
||||||
|
@ -65,13 +51,6 @@ public:
|
||||||
//! \return Returns value of the attribute previously set by setAttribute()
|
//! \return Returns value of the attribute previously set by setAttribute()
|
||||||
virtual s32 getAttributeAsInt(const c8 *attributeName, irr::s32 defaultNotFound = 0) const = 0;
|
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
|
Float Attribute
|
||||||
|
@ -90,13 +69,6 @@ public:
|
||||||
//! \return Returns value of the attribute previously set by setAttribute()
|
//! \return Returns value of the attribute previously set by setAttribute()
|
||||||
virtual f32 getAttributeAsFloat(const c8 *attributeName, irr::f32 defaultNotFound = 0.f) const = 0;
|
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
|
Bool Attribute
|
||||||
*/
|
*/
|
||||||
|
@ -112,13 +84,6 @@ public:
|
||||||
//! \param defaultNotFound Value returned when attributeName was not found
|
//! \param defaultNotFound Value returned when attributeName was not found
|
||||||
//! \return Returns value of the attribute previously set by setAttribute()
|
//! \return Returns value of the attribute previously set by setAttribute()
|
||||||
virtual bool getAttributeAsBool(const c8 *attributeName, bool defaultNotFound = false) const = 0;
|
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
|
} // end namespace io
|
||||||
|
|
|
@ -85,113 +85,6 @@ public:
|
||||||
See IReferenceCounted::drop() for more information. */
|
See IReferenceCounted::drop() for more information. */
|
||||||
virtual IWriteFile *createAndWriteFile(const path &filename, bool append = false) = 0;
|
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.
|
//! Adds an external archive loader to the engine.
|
||||||
/** Use this function to add support for new archive types to the
|
/** Use this function to add support for new archive types to the
|
||||||
engine, for example proprietary or encrypted file storage. */
|
engine, for example proprietary or encrypted file storage. */
|
||||||
|
|
|
@ -7,45 +7,39 @@
|
||||||
#include "IReferenceCounted.h"
|
#include "IReferenceCounted.h"
|
||||||
#include "irrArray.h"
|
#include "irrArray.h"
|
||||||
#include "EHardwareBufferFlags.h"
|
#include "EHardwareBufferFlags.h"
|
||||||
|
#include "EPrimitiveTypes.h"
|
||||||
#include "SVertexIndex.h"
|
#include "SVertexIndex.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace video
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace scene
|
namespace scene
|
||||||
{
|
{
|
||||||
|
|
||||||
class IIndexBuffer : public virtual IReferenceCounted
|
class IIndexBuffer : public virtual IReferenceCounted
|
||||||
{
|
{
|
||||||
public:
|
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 void *getData() = 0;
|
||||||
|
|
||||||
virtual video::E_INDEX_TYPE getType() const = 0;
|
//! Get amount of indices in this meshbuffer.
|
||||||
virtual void setType(video::E_INDEX_TYPE IndexType) = 0;
|
/** \return Number of indices in this buffer. */
|
||||||
|
virtual u32 getCount() const = 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 the current hardware mapping hint
|
//! get the current hardware mapping hint
|
||||||
virtual E_HARDWARE_MAPPING getHardwareMappingHint() const = 0;
|
virtual E_HARDWARE_MAPPING getHardwareMappingHint() const = 0;
|
||||||
|
|
||||||
//! set the hardware mapping hint, for driver
|
//! 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
|
//! flags the meshbuffer as changed, reloads hardware buffers
|
||||||
virtual void setDirty() = 0;
|
virtual void setDirty() = 0;
|
||||||
|
@ -53,6 +47,35 @@ public:
|
||||||
//! Get the currently used ID for identification of changes.
|
//! Get the currently used ID for identification of changes.
|
||||||
/** This shouldn't be used for anything outside the VideoDriver. */
|
/** This shouldn't be used for anything outside the VideoDriver. */
|
||||||
virtual u32 getChangedID() const = 0;
|
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
|
} // end namespace scene
|
||||||
|
|
|
@ -86,6 +86,17 @@ public:
|
||||||
mesh buffer. */
|
mesh buffer. */
|
||||||
virtual IMeshBuffer *getMeshBuffer(const video::SMaterial &material) const = 0;
|
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.
|
//! Get an axis aligned bounding box of the mesh.
|
||||||
/** \return Bounding box of this mesh. */
|
/** \return Bounding box of this mesh. */
|
||||||
virtual const core::aabbox3d<f32> &getBoundingBox() const = 0;
|
virtual const core::aabbox3d<f32> &getBoundingBox() const = 0;
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include "IReferenceCounted.h"
|
#include "IReferenceCounted.h"
|
||||||
#include "SMaterial.h"
|
#include "SMaterial.h"
|
||||||
#include "aabbox3d.h"
|
#include "aabbox3d.h"
|
||||||
#include "S3DVertex.h"
|
#include "IVertexBuffer.h"
|
||||||
#include "SVertexIndex.h"
|
#include "IIndexBuffer.h"
|
||||||
#include "EHardwareBufferFlags.h"
|
#include "EHardwareBufferFlags.h"
|
||||||
#include "EPrimitiveTypes.h"
|
#include "EPrimitiveTypes.h"
|
||||||
|
|
||||||
|
@ -46,39 +46,17 @@ public:
|
||||||
/** \return Material of this buffer. */
|
/** \return Material of this buffer. */
|
||||||
virtual const video::SMaterial &getMaterial() const = 0;
|
virtual const video::SMaterial &getMaterial() const = 0;
|
||||||
|
|
||||||
//! Get type of vertex data which is stored in this meshbuffer.
|
/// Get the vertex buffer
|
||||||
/** \return Vertex type of this buffer. */
|
virtual const scene::IVertexBuffer *getVertexBuffer() const = 0;
|
||||||
virtual video::E_VERTEX_TYPE getVertexType() const = 0;
|
|
||||||
|
|
||||||
//! Get access to vertex data. The data is an array of vertices.
|
/// Get the vertex buffer
|
||||||
/** Which vertex type is used can be determined by getVertexType().
|
virtual scene::IVertexBuffer *getVertexBuffer() = 0;
|
||||||
\return Pointer to array of vertices. */
|
|
||||||
virtual const void *getVertices() const = 0;
|
|
||||||
|
|
||||||
//! Get access to vertex data. The data is an array of vertices.
|
/// Get the index buffer
|
||||||
/** Which vertex type is used can be determined by getVertexType().
|
virtual const scene::IIndexBuffer *getIndexBuffer() const = 0;
|
||||||
\return Pointer to array of vertices. */
|
|
||||||
virtual void *getVertices() = 0;
|
|
||||||
|
|
||||||
//! Get amount of vertices in meshbuffer.
|
/// Get the index buffer
|
||||||
/** \return Number of vertices in this buffer. */
|
virtual scene::IIndexBuffer *getIndexBuffer() = 0;
|
||||||
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 axis aligned bounding box of this meshbuffer.
|
//! Get the axis aligned bounding box of this meshbuffer.
|
||||||
/** \return Axis aligned bounding box of this buffer. */
|
/** \return Axis aligned bounding box of this buffer. */
|
||||||
|
@ -92,24 +70,6 @@ public:
|
||||||
//! Recalculates the bounding box. Should be called if the mesh changed.
|
//! Recalculates the bounding box. Should be called if the mesh changed.
|
||||||
virtual void recalculateBoundingBox() = 0;
|
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
|
//! Append the vertices and indices to the current buffer
|
||||||
/** Only works for compatible vertex types.
|
/** Only works for compatible vertex types.
|
||||||
\param vertices Pointer to a vertex array.
|
\param vertices Pointer to a vertex array.
|
||||||
|
@ -118,29 +78,123 @@ public:
|
||||||
\param numIndices Number of indices in array. */
|
\param numIndices Number of indices in array. */
|
||||||
virtual void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) = 0;
|
virtual void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) = 0;
|
||||||
|
|
||||||
//! get the current hardware mapping hint
|
/* Leftover functions that are now just helpers for accessing the respective buffer. */
|
||||||
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const = 0;
|
|
||||||
|
|
||||||
//! get the current hardware mapping hint
|
//! Get type of vertex data which is stored in this meshbuffer.
|
||||||
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const = 0;
|
/** \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
|
//! 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
|
//! 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.
|
/* End helpers */
|
||||||
/** 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;
|
|
||||||
|
|
||||||
//! Describe what kind of primitive geometry is used by the meshbuffer
|
//! Describe what kind of primitive geometry is used by the meshbuffer
|
||||||
/** Note: Default is EPT_TRIANGLES. Using other types is fine for rendering.
|
/** Note: Default is EPT_TRIANGLES. Using other types is fine for rendering.
|
||||||
|
@ -153,32 +207,13 @@ public:
|
||||||
virtual E_PRIMITIVE_TYPE getPrimitiveType() const = 0;
|
virtual E_PRIMITIVE_TYPE getPrimitiveType() const = 0;
|
||||||
|
|
||||||
//! Calculate how many geometric primitives are used by this meshbuffer
|
//! Calculate how many geometric primitives are used by this meshbuffer
|
||||||
virtual u32 getPrimitiveCount() const
|
u32 getPrimitiveCount() const
|
||||||
{
|
{
|
||||||
const u32 indexCount = getIndexCount();
|
return getIndexBuffer()->getPrimitiveCount(getPrimitiveType());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Calculate size of vertices and indices in memory
|
//! Calculate size of vertices and indices in memory
|
||||||
virtual size_t getSize() const
|
size_t getSize() const
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
switch (getVertexType()) {
|
switch (getVertexType()) {
|
||||||
|
|
|
@ -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.
|
//! Grabs the object. Increments the reference counter by one.
|
||||||
/** Someone who calls grab() to an object, should later also
|
/** Someone who calls grab() to an object, should later also
|
||||||
call drop() to it. If an object never gets as much drop() as
|
call drop() to it. If an object never gets as much drop() as
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "EDebugSceneTypes.h"
|
#include "EDebugSceneTypes.h"
|
||||||
#include "SMaterial.h"
|
#include "SMaterial.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
|
#include "irrArray.h"
|
||||||
#include "aabbox3d.h"
|
#include "aabbox3d.h"
|
||||||
#include "matrix4.h"
|
#include "matrix4.h"
|
||||||
#include "IAttributes.h"
|
#include "IAttributes.h"
|
||||||
|
|
|
@ -199,6 +199,9 @@ public:
|
||||||
//! Adds a new meshbuffer to the mesh, access it as last one
|
//! Adds a new meshbuffer to the mesh, access it as last one
|
||||||
virtual SSkinMeshBuffer *addMeshBuffer() = 0;
|
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
|
//! Adds a new joint to the mesh, access it as last one
|
||||||
virtual SJoint *addJoint(SJoint *parent = 0) = 0;
|
virtual SJoint *addJoint(SJoint *parent = 0) = 0;
|
||||||
|
|
||||||
|
|
|
@ -17,24 +17,47 @@ namespace scene
|
||||||
class IVertexBuffer : public virtual IReferenceCounted
|
class IVertexBuffer : public virtual IReferenceCounted
|
||||||
{
|
{
|
||||||
public:
|
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 video::E_VERTEX_TYPE getType() const = 0;
|
||||||
virtual void setType(video::E_VERTEX_TYPE vertexType) = 0;
|
|
||||||
virtual u32 stride() const = 0;
|
//! Get access to vertex data. The data is an array of vertices.
|
||||||
virtual u32 size() const = 0;
|
/** Which vertex type is used can be determined by getVertexType().
|
||||||
virtual void push_back(const video::S3DVertex &element) = 0;
|
\return Pointer to array of vertices. */
|
||||||
virtual video::S3DVertex &operator[](const u32 index) const = 0;
|
virtual const void *getData() const = 0;
|
||||||
virtual video::S3DVertex &getLast() = 0;
|
|
||||||
virtual void set_used(u32 usedNow) = 0;
|
//! Get access to vertex data. The data is an array of vertices.
|
||||||
virtual void reallocate(u32 new_size) = 0;
|
/** Which vertex type is used can be determined by getVertexType().
|
||||||
virtual u32 allocated_size() const = 0;
|
\return Pointer to array of vertices. */
|
||||||
virtual video::S3DVertex *pointer() = 0;
|
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
|
//! get the current hardware mapping hint
|
||||||
virtual E_HARDWARE_MAPPING getHardwareMappingHint() const = 0;
|
virtual E_HARDWARE_MAPPING getHardwareMappingHint() const = 0;
|
||||||
|
|
||||||
//! set the hardware mapping hint, for driver
|
//! 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
|
//! flags the meshbuffer as changed, reloads hardware buffers
|
||||||
virtual void setDirty() = 0;
|
virtual void setDirty() = 0;
|
||||||
|
@ -42,6 +65,10 @@ public:
|
||||||
//! Get the currently used ID for identification of changes.
|
//! Get the currently used ID for identification of changes.
|
||||||
/** This shouldn't be used for anything outside the VideoDriver. */
|
/** This shouldn't be used for anything outside the VideoDriver. */
|
||||||
virtual u32 getChangedID() const = 0;
|
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
|
} // end namespace scene
|
||||||
|
|
|
@ -9,14 +9,16 @@
|
||||||
#include "ITexture.h"
|
#include "ITexture.h"
|
||||||
#include "irrArray.h"
|
#include "irrArray.h"
|
||||||
#include "matrix4.h"
|
#include "matrix4.h"
|
||||||
#include "plane3d.h"
|
|
||||||
#include "dimension2d.h"
|
#include "dimension2d.h"
|
||||||
#include "position2d.h"
|
#include "position2d.h"
|
||||||
#include "IMeshBuffer.h"
|
|
||||||
#include "EDriverTypes.h"
|
#include "EDriverTypes.h"
|
||||||
#include "EDriverFeatures.h"
|
#include "EDriverFeatures.h"
|
||||||
|
#include "EPrimitiveTypes.h"
|
||||||
|
#include "EVideoTypes.h"
|
||||||
#include "SExposedVideoData.h"
|
#include "SExposedVideoData.h"
|
||||||
#include "SOverrideMaterial.h"
|
#include "SOverrideMaterial.h"
|
||||||
|
#include "S3DVertex.h" // E_VERTEX_TYPE
|
||||||
|
#include "SVertexIndex.h" // E_INDEX_TYPE
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
@ -29,6 +31,8 @@ class IWriteFile;
|
||||||
namespace scene
|
namespace scene
|
||||||
{
|
{
|
||||||
class IMeshBuffer;
|
class IMeshBuffer;
|
||||||
|
class IVertexBuffer;
|
||||||
|
class IIndexBuffer;
|
||||||
class IMesh;
|
class IMesh;
|
||||||
class IMeshManipulator;
|
class IMeshManipulator;
|
||||||
class ISceneNode;
|
class ISceneNode;
|
||||||
|
@ -36,77 +40,12 @@ class ISceneNode;
|
||||||
|
|
||||||
namespace video
|
namespace video
|
||||||
{
|
{
|
||||||
struct S3DVertex;
|
|
||||||
struct S3DVertex2TCoords;
|
|
||||||
struct S3DVertexTangents;
|
|
||||||
class IImageLoader;
|
class IImageLoader;
|
||||||
class IImageWriter;
|
class IImageWriter;
|
||||||
class IMaterialRenderer;
|
class IMaterialRenderer;
|
||||||
class IGPUProgrammingServices;
|
class IGPUProgrammingServices;
|
||||||
class IRenderTarget;
|
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[] = {
|
const c8 *const FogTypeNames[] = {
|
||||||
"FogExp",
|
"FogExp",
|
||||||
"FogLinear",
|
"FogLinear",
|
||||||
|
@ -114,6 +53,15 @@ const c8 *const FogTypeNames[] = {
|
||||||
0,
|
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.
|
//! Interface to driver which is able to perform 2d and 3d graphics functions.
|
||||||
/** This interface is one of the most important interfaces of
|
/** This interface is one of the most important interfaces of
|
||||||
the Irrlicht Engine: All rendering and texture manipulation is done with
|
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.
|
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.
|
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.
|
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
|
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.
|
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).
|
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;
|
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.
|
//! Sets transformation matrices.
|
||||||
/** \param state Transformation type to be set, e.g. view,
|
/** \param state Transformation type to be set, e.g. view,
|
||||||
world, or projection.
|
world, or projection.
|
||||||
|
@ -360,7 +301,10 @@ public:
|
||||||
virtual void removeAllTextures() = 0;
|
virtual void removeAllTextures() = 0;
|
||||||
|
|
||||||
//! Remove hardware buffer
|
//! 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
|
//! Remove all hardware buffers
|
||||||
virtual void removeAllHardwareBuffers() = 0;
|
virtual void removeAllHardwareBuffers() = 0;
|
||||||
|
@ -799,6 +743,17 @@ public:
|
||||||
/** \param mb Buffer to draw */
|
/** \param mb Buffer to draw */
|
||||||
virtual void drawMeshBuffer(const scene::IMeshBuffer *mb) = 0;
|
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
|
//! Draws normals of a mesh buffer
|
||||||
/** \param mb Buffer to draw the normals of
|
/** \param mb Buffer to draw the normals of
|
||||||
\param length length scale factor of the normals
|
\param length length scale factor of the normals
|
||||||
|
@ -856,12 +811,8 @@ public:
|
||||||
\return Approximate amount of frames per second drawn. */
|
\return Approximate amount of frames per second drawn. */
|
||||||
virtual s32 getFPS() const = 0;
|
virtual s32 getFPS() const = 0;
|
||||||
|
|
||||||
//! Returns amount of primitives (mostly triangles) which were drawn in the last frame.
|
//! Return some statistics about the last frame
|
||||||
/** Together with getFPS() very useful method for statistics.
|
virtual SFrameStats getFrameStats() const = 0;
|
||||||
\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;
|
|
||||||
|
|
||||||
//! Gets name of this video driver.
|
//! Gets name of this video driver.
|
||||||
/** \return Returns the name of the video driver, e.g. in case
|
/** \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. */
|
\return Pointer to loaded texture, or 0 if not found. */
|
||||||
virtual video::ITexture *findTexture(const io::path &filename) = 0;
|
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
|
//! Set the minimum number of vertices for which a hw buffer will be created
|
||||||
/** \param count Number of vertices to set as minimum. */
|
/** \param count Number of vertices to set as minimum. */
|
||||||
virtual void setMinHardwareBufferVertexCount(u32 count) = 0;
|
virtual void setMinHardwareBufferVertexCount(u32 count) = 0;
|
||||||
|
|
|
@ -6,14 +6,16 @@
|
||||||
|
|
||||||
#include "IReferenceCounted.h"
|
#include "IReferenceCounted.h"
|
||||||
#include "dimension2d.h"
|
#include "dimension2d.h"
|
||||||
#include "IVideoDriver.h"
|
|
||||||
#include "EDriverTypes.h"
|
#include "EDriverTypes.h"
|
||||||
#include "EDeviceTypes.h"
|
#include "EDeviceTypes.h"
|
||||||
#include "IEventReceiver.h"
|
#include "IEventReceiver.h"
|
||||||
#include "ICursorControl.h"
|
#include "ICursorControl.h"
|
||||||
#include "ITimer.h"
|
#include "ITimer.h"
|
||||||
#include "IOSOperator.h"
|
#include "IOSOperator.h"
|
||||||
|
#include "irrArray.h"
|
||||||
#include "IrrCompileConfig.h"
|
#include "IrrCompileConfig.h"
|
||||||
|
#include "position2d.h"
|
||||||
|
#include "SColor.h" // video::ECOLOR_FORMAT
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
@ -38,6 +40,9 @@ class ISceneManager;
|
||||||
namespace video
|
namespace video
|
||||||
{
|
{
|
||||||
class IContextManager;
|
class IContextManager;
|
||||||
|
class IImage;
|
||||||
|
class ITexture;
|
||||||
|
class IVideoDriver;
|
||||||
extern "C" IRRLICHT_API bool IRRCALLCONV isDriverSupported(E_DRIVER_TYPE driver);
|
extern "C" IRRLICHT_API bool IRRCALLCONV isDriverSupported(E_DRIVER_TYPE driver);
|
||||||
} // end namespace video
|
} // end namespace video
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include "IAnimatedMesh.h"
|
#include "IAnimatedMesh.h"
|
||||||
#include "IMesh.h"
|
#include "IMesh.h"
|
||||||
#include "aabbox3d.h"
|
#include "aabbox3d.h"
|
||||||
#include "irrArray.h"
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace scene
|
||||||
{
|
{
|
||||||
|
|
||||||
//! Simple implementation of the IAnimatedMesh interface.
|
//! Simple implementation of the IAnimatedMesh interface.
|
||||||
struct SAnimatedMesh : public IAnimatedMesh
|
struct SAnimatedMesh final : public IAnimatedMesh
|
||||||
{
|
{
|
||||||
//! constructor
|
//! constructor
|
||||||
SAnimatedMesh(scene::IMesh *mesh = 0, scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) :
|
SAnimatedMesh(scene::IMesh *mesh = 0, scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) :
|
||||||
|
@ -32,15 +32,15 @@ struct SAnimatedMesh : public IAnimatedMesh
|
||||||
virtual ~SAnimatedMesh()
|
virtual ~SAnimatedMesh()
|
||||||
{
|
{
|
||||||
// drop meshes
|
// drop meshes
|
||||||
for (u32 i = 0; i < Meshes.size(); ++i)
|
for (auto *mesh : Meshes)
|
||||||
Meshes[i]->drop();
|
mesh->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Gets the frame count of the animated mesh.
|
//! Gets the frame count of the animated mesh.
|
||||||
/** \return Amount of frames. If the amount is 1, it is a static, non animated mesh. */
|
/** \return Amount of frames. If the amount is 1, it is a static, non animated mesh. */
|
||||||
u32 getFrameCount() const override
|
u32 getFrameCount() const override
|
||||||
{
|
{
|
||||||
return Meshes.size();
|
return static_cast<u32>(Meshes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Gets the default animation speed of the animated mesh.
|
//! Gets the default animation speed of the animated mesh.
|
||||||
|
@ -161,7 +161,7 @@ struct SAnimatedMesh : public IAnimatedMesh
|
||||||
}
|
}
|
||||||
|
|
||||||
//! All meshes defining the animated mesh
|
//! All meshes defining the animated mesh
|
||||||
core::array<IMesh *> Meshes;
|
std::vector<IMesh *> Meshes;
|
||||||
|
|
||||||
//! The bounding box of this mesh
|
//! The bounding box of this mesh
|
||||||
core::aabbox3d<f32> Box;
|
core::aabbox3d<f32> Box;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include "SColor.h"
|
#include "SColor.h"
|
||||||
#include "matrix4.h"
|
#include "matrix4.h"
|
||||||
#include "irrArray.h"
|
|
||||||
#include "irrMath.h"
|
#include "irrMath.h"
|
||||||
#include "EMaterialTypes.h"
|
#include "EMaterialTypes.h"
|
||||||
#include "EMaterialProps.h"
|
#include "EMaterialProps.h"
|
||||||
|
|
|
@ -4,17 +4,17 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include "IMesh.h"
|
#include "IMesh.h"
|
||||||
#include "IMeshBuffer.h"
|
#include "IMeshBuffer.h"
|
||||||
#include "aabbox3d.h"
|
#include "aabbox3d.h"
|
||||||
#include "irrArray.h"
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace scene
|
namespace scene
|
||||||
{
|
{
|
||||||
//! Simple implementation of the IMesh interface.
|
//! Simple implementation of the IMesh interface.
|
||||||
struct SMesh : public IMesh
|
struct SMesh final : public IMesh
|
||||||
{
|
{
|
||||||
//! constructor
|
//! constructor
|
||||||
SMesh()
|
SMesh()
|
||||||
|
@ -28,15 +28,15 @@ struct SMesh : public IMesh
|
||||||
virtual ~SMesh()
|
virtual ~SMesh()
|
||||||
{
|
{
|
||||||
// drop buffers
|
// drop buffers
|
||||||
for (u32 i = 0; i < MeshBuffers.size(); ++i)
|
for (auto *buf : MeshBuffers)
|
||||||
MeshBuffers[i]->drop();
|
buf->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! clean mesh
|
//! clean mesh
|
||||||
virtual void clear()
|
virtual void clear()
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < MeshBuffers.size(); ++i)
|
for (auto *buf : MeshBuffers)
|
||||||
MeshBuffers[i]->drop();
|
buf->drop();
|
||||||
MeshBuffers.clear();
|
MeshBuffers.clear();
|
||||||
BoundingBox.reset(0.f, 0.f, 0.f);
|
BoundingBox.reset(0.f, 0.f, 0.f);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ struct SMesh : public IMesh
|
||||||
//! returns amount of mesh buffers.
|
//! returns amount of mesh buffers.
|
||||||
u32 getMeshBufferCount() const override
|
u32 getMeshBufferCount() const override
|
||||||
{
|
{
|
||||||
return MeshBuffers.size();
|
return static_cast<u32>(MeshBuffers.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! returns pointer to a mesh buffer
|
//! returns pointer to a mesh buffer
|
||||||
|
@ -57,14 +57,24 @@ struct SMesh : public IMesh
|
||||||
/** reverse search */
|
/** reverse search */
|
||||||
IMeshBuffer *getMeshBuffer(const video::SMaterial &material) const override
|
IMeshBuffer *getMeshBuffer(const video::SMaterial &material) const override
|
||||||
{
|
{
|
||||||
for (s32 i = (s32)MeshBuffers.size() - 1; i >= 0; --i) {
|
for (auto it = MeshBuffers.rbegin(); it != MeshBuffers.rend(); it++) {
|
||||||
if (material == MeshBuffers[i]->getMaterial())
|
if (material == (*it)->getMaterial())
|
||||||
return MeshBuffers[i];
|
return *it;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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
|
//! returns an axis aligned bounding box
|
||||||
const core::aabbox3d<f32> &getBoundingBox() const override
|
const core::aabbox3d<f32> &getBoundingBox() const override
|
||||||
{
|
{
|
||||||
|
@ -81,8 +91,8 @@ struct SMesh : public IMesh
|
||||||
void recalculateBoundingBox()
|
void recalculateBoundingBox()
|
||||||
{
|
{
|
||||||
bool hasMeshBufferBBox = false;
|
bool hasMeshBufferBBox = false;
|
||||||
for (u32 i = 0; i < MeshBuffers.size(); ++i) {
|
for (auto *buf : MeshBuffers) {
|
||||||
const core::aabbox3df &bb = MeshBuffers[i]->getBoundingBox();
|
const core::aabbox3df &bb = buf->getBoundingBox();
|
||||||
if (!bb.isEmpty()) {
|
if (!bb.isEmpty()) {
|
||||||
if (!hasMeshBufferBBox) {
|
if (!hasMeshBufferBBox) {
|
||||||
hasMeshBufferBBox = true;
|
hasMeshBufferBBox = true;
|
||||||
|
@ -104,25 +114,28 @@ struct SMesh : public IMesh
|
||||||
if (buf) {
|
if (buf) {
|
||||||
buf->grab();
|
buf->grab();
|
||||||
MeshBuffers.push_back(buf);
|
MeshBuffers.push_back(buf);
|
||||||
|
TextureSlots.push_back(getMeshBufferCount() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! set the hardware mapping hint, for driver
|
//! set the hardware mapping hint, for driver
|
||||||
void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override
|
void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < MeshBuffers.size(); ++i)
|
for (auto *buf : MeshBuffers)
|
||||||
MeshBuffers[i]->setHardwareMappingHint(newMappingHint, buffer);
|
buf->setHardwareMappingHint(newMappingHint, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! flags the meshbuffer as changed, reloads hardware buffers
|
//! flags the meshbuffer as changed, reloads hardware buffers
|
||||||
void setDirty(E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override
|
void setDirty(E_BUFFER_TYPE buffer = EBT_VERTEX_AND_INDEX) override
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < MeshBuffers.size(); ++i)
|
for (auto *buf : MeshBuffers)
|
||||||
MeshBuffers[i]->setDirty(buffer);
|
buf->setDirty(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! The meshbuffers of this mesh
|
//! 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
|
//! The bounding box of this mesh
|
||||||
core::aabbox3d<f32> BoundingBox;
|
core::aabbox3d<f32> BoundingBox;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include "SMaterial.h"
|
#include "SMaterial.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
|
@ -57,7 +58,7 @@ struct SOverrideMaterial
|
||||||
};
|
};
|
||||||
|
|
||||||
//! To overwrite SMaterial::MaterialType
|
//! To overwrite SMaterial::MaterialType
|
||||||
core::array<SMaterialTypeReplacement> MaterialTypes;
|
std::vector<SMaterialTypeReplacement> MaterialTypes;
|
||||||
|
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
SOverrideMaterial() :
|
SOverrideMaterial() :
|
||||||
|
@ -83,9 +84,8 @@ struct SOverrideMaterial
|
||||||
void apply(SMaterial &material)
|
void apply(SMaterial &material)
|
||||||
{
|
{
|
||||||
if (Enabled) {
|
if (Enabled) {
|
||||||
for (u32 i = 0; i < MaterialTypes.size(); ++i) {
|
for (const auto &mtr : MaterialTypes) {
|
||||||
const SMaterialTypeReplacement &mtr = MaterialTypes[i];
|
if (mtr.Original < 0 || mtr.Original == (s32)material.MaterialType)
|
||||||
if (mtr.Original < 0 || (s32)mtr.Original == material.MaterialType)
|
|
||||||
material.MaterialType = (E_MATERIAL_TYPE)mtr.Replacement;
|
material.MaterialType = (E_MATERIAL_TYPE)mtr.Replacement;
|
||||||
}
|
}
|
||||||
for (u32 f = 0; f < 32; ++f) {
|
for (u32 f = 0; f < 32; ++f) {
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IMeshBuffer.h"
|
#include "IMeshBuffer.h"
|
||||||
|
#include "CVertexBuffer.h"
|
||||||
|
#include "CIndexBuffer.h"
|
||||||
#include "S3DVertex.h"
|
#include "S3DVertex.h"
|
||||||
|
#include "irrArray.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
@ -13,19 +16,36 @@ namespace scene
|
||||||
{
|
{
|
||||||
|
|
||||||
//! A mesh buffer able to choose between S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
|
//! A mesh buffer able to choose between S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
|
||||||
struct SSkinMeshBuffer : public IMeshBuffer
|
struct SSkinMeshBuffer final : public IMeshBuffer
|
||||||
{
|
{
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
SSkinMeshBuffer(video::E_VERTEX_TYPE vt = video::EVT_STANDARD) :
|
SSkinMeshBuffer(video::E_VERTEX_TYPE vt = video::EVT_STANDARD) :
|
||||||
ChangedID_Vertex(1), ChangedID_Index(1), VertexType(vt),
|
VertexType(vt), PrimitiveType(EPT_TRIANGLES),
|
||||||
PrimitiveType(EPT_TRIANGLES),
|
|
||||||
MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER),
|
|
||||||
HWBuffer(NULL),
|
|
||||||
BoundingBoxNeedsRecalculated(true)
|
BoundingBoxNeedsRecalculated(true)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
setDebugName("SSkinMeshBuffer");
|
setDebugName("SSkinMeshBuffer");
|
||||||
#endif
|
#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.
|
//! Get Material of this buffer.
|
||||||
|
@ -40,83 +60,53 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||||
return Material;
|
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
|
//! Get standard vertex at given index
|
||||||
virtual video::S3DVertex *getVertex(u32 index)
|
virtual video::S3DVertex *getVertex(u32 index)
|
||||||
{
|
{
|
||||||
switch (VertexType) {
|
switch (VertexType) {
|
||||||
case video::EVT_2TCOORDS:
|
case video::EVT_2TCOORDS:
|
||||||
return (video::S3DVertex *)&Vertices_2TCoords[index];
|
return &Vertices_2TCoords->Data[index];
|
||||||
case video::EVT_TANGENTS:
|
case video::EVT_TANGENTS:
|
||||||
return (video::S3DVertex *)&Vertices_Tangents[index];
|
return &Vertices_Tangents->Data[index];
|
||||||
default:
|
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
|
//! Get bounding box
|
||||||
const core::aabbox3d<f32> &getBoundingBox() const override
|
const core::aabbox3d<f32> &getBoundingBox() const override
|
||||||
{
|
{
|
||||||
|
@ -129,6 +119,28 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||||
BoundingBox = box;
|
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
|
//! Recalculate bounding box
|
||||||
void recalculateBoundingBox() override
|
void recalculateBoundingBox() override
|
||||||
{
|
{
|
||||||
|
@ -139,57 +151,30 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||||
|
|
||||||
switch (VertexType) {
|
switch (VertexType) {
|
||||||
case video::EVT_STANDARD: {
|
case video::EVT_STANDARD: {
|
||||||
if (Vertices_Standard.empty())
|
recalculateBoundingBox(Vertices_Standard);
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case video::EVT_2TCOORDS: {
|
case video::EVT_2TCOORDS: {
|
||||||
if (Vertices_2TCoords.empty())
|
recalculateBoundingBox(Vertices_2TCoords);
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case video::EVT_TANGENTS: {
|
case video::EVT_TANGENTS: {
|
||||||
if (Vertices_Tangents.empty())
|
recalculateBoundingBox(Vertices_Tangents);
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get vertex type
|
|
||||||
video::E_VERTEX_TYPE getVertexType() const override
|
|
||||||
{
|
|
||||||
return VertexType;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Convert to 2tcoords vertex type
|
//! Convert to 2tcoords vertex type
|
||||||
void convertTo2TCoords()
|
void convertTo2TCoords()
|
||||||
{
|
{
|
||||||
if (VertexType == video::EVT_STANDARD) {
|
if (VertexType == video::EVT_STANDARD) {
|
||||||
for (u32 n = 0; n < Vertices_Standard.size(); ++n) {
|
|
||||||
video::S3DVertex2TCoords Vertex;
|
video::S3DVertex2TCoords Vertex;
|
||||||
Vertex.Color = Vertices_Standard[n].Color;
|
for (const auto &Vertex_Standard : Vertices_Standard->Data) {
|
||||||
Vertex.Pos = Vertices_Standard[n].Pos;
|
copyVertex(Vertex_Standard, Vertex);
|
||||||
Vertex.Normal = Vertices_Standard[n].Normal;
|
Vertices_2TCoords->Data.push_back(Vertex);
|
||||||
Vertex.TCoords = Vertices_Standard[n].TCoords;
|
|
||||||
Vertices_2TCoords.push_back(Vertex);
|
|
||||||
}
|
}
|
||||||
Vertices_Standard.clear();
|
Vertices_Standard->Data.clear();
|
||||||
VertexType = video::EVT_2TCOORDS;
|
VertexType = video::EVT_2TCOORDS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,134 +183,28 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||||
void convertToTangents()
|
void convertToTangents()
|
||||||
{
|
{
|
||||||
if (VertexType == video::EVT_STANDARD) {
|
if (VertexType == video::EVT_STANDARD) {
|
||||||
for (u32 n = 0; n < Vertices_Standard.size(); ++n) {
|
|
||||||
video::S3DVertexTangents Vertex;
|
video::S3DVertexTangents Vertex;
|
||||||
Vertex.Color = Vertices_Standard[n].Color;
|
for (const auto &Vertex_Standard : Vertices_Standard->Data) {
|
||||||
Vertex.Pos = Vertices_Standard[n].Pos;
|
copyVertex(Vertex_Standard, Vertex);
|
||||||
Vertex.Normal = Vertices_Standard[n].Normal;
|
Vertices_Tangents->Data.push_back(Vertex);
|
||||||
Vertex.TCoords = Vertices_Standard[n].TCoords;
|
|
||||||
Vertices_Tangents.push_back(Vertex);
|
|
||||||
}
|
}
|
||||||
Vertices_Standard.clear();
|
Vertices_Standard->Data.clear();
|
||||||
VertexType = video::EVT_TANGENTS;
|
VertexType = video::EVT_TANGENTS;
|
||||||
} else if (VertexType == video::EVT_2TCOORDS) {
|
} else if (VertexType == video::EVT_2TCOORDS) {
|
||||||
for (u32 n = 0; n < Vertices_2TCoords.size(); ++n) {
|
|
||||||
video::S3DVertexTangents Vertex;
|
video::S3DVertexTangents Vertex;
|
||||||
Vertex.Color = Vertices_2TCoords[n].Color;
|
for (const auto &Vertex_2TCoords : Vertices_2TCoords->Data) {
|
||||||
Vertex.Pos = Vertices_2TCoords[n].Pos;
|
copyVertex(Vertex_2TCoords, Vertex);
|
||||||
Vertex.Normal = Vertices_2TCoords[n].Normal;
|
Vertices_Tangents->Data.push_back(Vertex);
|
||||||
Vertex.TCoords = Vertices_2TCoords[n].TCoords;
|
|
||||||
Vertices_Tangents.push_back(Vertex);
|
|
||||||
}
|
}
|
||||||
Vertices_2TCoords.clear();
|
Vertices_2TCoords->Data.clear();
|
||||||
VertexType = video::EVT_TANGENTS;
|
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
|
//! append the vertices and indices to the current buffer
|
||||||
void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) override {}
|
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
|
|
||||||
{
|
{
|
||||||
return MappingHint_Vertex;
|
_IRR_DEBUG_BREAK_IF(true);
|
||||||
}
|
|
||||||
|
|
||||||
//! 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Describe what kind of primitive geometry is used by the meshbuffer
|
//! Describe what kind of primitive geometry is used by the meshbuffer
|
||||||
|
@ -340,41 +219,14 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||||
return PrimitiveType;
|
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.
|
//! Call this after changing the positions of any vertex.
|
||||||
void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; }
|
void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; }
|
||||||
|
|
||||||
core::array<video::S3DVertexTangents> Vertices_Tangents;
|
SVertexBufferTangents *Vertices_Tangents;
|
||||||
core::array<video::S3DVertex2TCoords> Vertices_2TCoords;
|
SVertexBufferLightMap *Vertices_2TCoords;
|
||||||
core::array<video::S3DVertex> Vertices_Standard;
|
SVertexBuffer *Vertices_Standard;
|
||||||
core::array<u16> Indices;
|
SIndexBuffer *Indices;
|
||||||
|
|
||||||
u32 ChangedID_Vertex;
|
|
||||||
u32 ChangedID_Index;
|
|
||||||
|
|
||||||
// ISkinnedMesh::SJoint *AttachedJoint;
|
|
||||||
core::matrix4 Transformation;
|
core::matrix4 Transformation;
|
||||||
|
|
||||||
video::SMaterial Material;
|
video::SMaterial Material;
|
||||||
|
@ -385,13 +237,7 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||||
//! Primitive type used for rendering (triangles, lines, ...)
|
//! Primitive type used for rendering (triangles, lines, ...)
|
||||||
E_PRIMITIVE_TYPE PrimitiveType;
|
E_PRIMITIVE_TYPE PrimitiveType;
|
||||||
|
|
||||||
// hardware mapping hint
|
bool BoundingBoxNeedsRecalculated;
|
||||||
E_HARDWARE_MAPPING MappingHint_Vertex : 3;
|
|
||||||
E_HARDWARE_MAPPING MappingHint_Index : 3;
|
|
||||||
|
|
||||||
mutable void *HWBuffer;
|
|
||||||
|
|
||||||
bool BoundingBoxNeedsRecalculated : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace scene
|
} // end namespace scene
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "line3d.h"
|
#include "line3d.h"
|
||||||
#include "aabbox3d.h"
|
#include "aabbox3d.h"
|
||||||
#include "matrix4.h"
|
#include "matrix4.h"
|
||||||
#include "IVideoDriver.h"
|
#include "EVideoTypes.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
//! Reallocates the array, make it bigger or smaller.
|
||||||
/** \param new_size New size of array.
|
/** \param new_size New size of array.
|
||||||
\param canShrink Specifies whether the array is reallocated even if
|
\param canShrink Specifies whether the array is reallocated even if
|
||||||
|
@ -167,13 +171,6 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
array<T> &operator=(std::vector<T> &&other)
|
|
||||||
{
|
|
||||||
m_data = std::move(other);
|
|
||||||
is_sorted = false;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Equality operator
|
//! Equality operator
|
||||||
bool operator==(const array<T> &other) const
|
bool operator==(const array<T> &other) const
|
||||||
{
|
{
|
||||||
|
@ -400,16 +397,6 @@ public:
|
||||||
std::swap(is_sorted, other.is_sorted);
|
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 T value_type;
|
||||||
typedef u32 size_type;
|
typedef u32 size_type;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cwchar>
|
#include <cwchar>
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
/* HACK: import these string methods from MT's util/string.h */
|
/* HACK: import these string methods from MT's util/string.h */
|
||||||
extern std::wstring utf8_to_wide(std::string_view input);
|
extern std::wstring utf8_to_wide(std::string_view input);
|
||||||
|
@ -65,6 +64,7 @@ static inline u32 locale_upper(u32 x)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class string
|
class string
|
||||||
{
|
{
|
||||||
|
using stl_type = std::basic_string<T>;
|
||||||
public:
|
public:
|
||||||
typedef T char_type;
|
typedef T char_type;
|
||||||
|
|
||||||
|
@ -79,6 +79,10 @@ public:
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string(const stl_type &str) : str(str) {}
|
||||||
|
|
||||||
|
string(stl_type &&str) : str(std::move(str)) {}
|
||||||
|
|
||||||
//! Constructor from other string types
|
//! Constructor from other string types
|
||||||
template <class B>
|
template <class B>
|
||||||
string(const string<B> &other)
|
string(const string<B> &other)
|
||||||
|
@ -814,13 +818,6 @@ public:
|
||||||
friend size_t wStringToUTF8(stringc &destination, const wchar_t *source);
|
friend size_t wStringToUTF8(stringc &destination, const wchar_t *source);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::basic_string<T> stl_type;
|
|
||||||
|
|
||||||
//! Private constructor
|
|
||||||
string(stl_type &&str) :
|
|
||||||
str(str)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//! strlen wrapper
|
//! strlen wrapper
|
||||||
template <typename U>
|
template <typename U>
|
||||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 4.7 KiB |
|
@ -1,123 +0,0 @@
|
||||||
#!/bin/bash -e
|
|
||||||
|
|
||||||
# NOTE: this code is mostly copied from minetest_android_deps
|
|
||||||
# <https://github.com/minetest/minetest_android_deps>
|
|
||||||
|
|
||||||
png_ver=1.6.40
|
|
||||||
jpeg_ver=3.0.1
|
|
||||||
|
|
||||||
download () {
|
|
||||||
get_tar_archive libpng "https://download.sourceforge.net/libpng/libpng-${png_ver}.tar.gz"
|
|
||||||
get_tar_archive libjpeg "https://download.sourceforge.net/libjpeg-turbo/libjpeg-turbo-${jpeg_ver}.tar.gz"
|
|
||||||
}
|
|
||||||
|
|
||||||
build () {
|
|
||||||
# Build libjpg and libpng first because Irrlicht needs them
|
|
||||||
mkdir -p libpng
|
|
||||||
pushd libpng
|
|
||||||
$srcdir/libpng/configure --host=$CROSS_PREFIX
|
|
||||||
make && make DESTDIR=$PWD install
|
|
||||||
popd
|
|
||||||
|
|
||||||
mkdir -p libjpeg
|
|
||||||
pushd libjpeg
|
|
||||||
cmake $srcdir/libjpeg "${CMAKE_FLAGS[@]}" -DENABLE_SHARED=OFF
|
|
||||||
make && make DESTDIR=$PWD install
|
|
||||||
popd
|
|
||||||
|
|
||||||
local libpng=$PWD/libpng/usr/local/lib/libpng.a
|
|
||||||
local libjpeg=$(echo $PWD/libjpeg/opt/libjpeg-turbo/lib*/libjpeg.a)
|
|
||||||
cmake $srcdir/irrlicht "${CMAKE_FLAGS[@]}" \
|
|
||||||
-DBUILD_SHARED_LIBS=OFF \
|
|
||||||
-DPNG_LIBRARY=$libpng \
|
|
||||||
-DPNG_PNG_INCLUDE_DIR=$(dirname "$libpng")/../include \
|
|
||||||
-DJPEG_LIBRARY=$libjpeg \
|
|
||||||
-DJPEG_INCLUDE_DIR=$(dirname "$libjpeg")/../include
|
|
||||||
make
|
|
||||||
|
|
||||||
cp -p lib/Android/libIrrlichtMt.a $libpng $libjpeg $pkgdir/
|
|
||||||
cp -a $srcdir/irrlicht/include $pkgdir/include
|
|
||||||
cp -a $srcdir/irrlicht/media/Shaders $pkgdir/Shaders
|
|
||||||
}
|
|
||||||
|
|
||||||
get_tar_archive () {
|
|
||||||
# $1: folder to extract to, $2: URL
|
|
||||||
local filename="${2##*/}"
|
|
||||||
[ -d "$1" ] && return 0
|
|
||||||
wget -c "$2" -O "$filename"
|
|
||||||
mkdir -p "$1"
|
|
||||||
tar -xaf "$filename" -C "$1" --strip-components=1
|
|
||||||
rm "$filename"
|
|
||||||
}
|
|
||||||
|
|
||||||
_setup_toolchain () {
|
|
||||||
local toolchain=$(echo "$ANDROID_NDK"/toolchains/llvm/prebuilt/*)
|
|
||||||
if [ ! -d "$toolchain" ]; then
|
|
||||||
echo "Android NDK path not specified or incorrect"; return 1
|
|
||||||
fi
|
|
||||||
export PATH="$toolchain/bin:$ANDROID_NDK:$PATH"
|
|
||||||
|
|
||||||
unset CFLAGS CPPFLAGS CXXFLAGS
|
|
||||||
|
|
||||||
TARGET_ABI="$1"
|
|
||||||
API=21
|
|
||||||
if [ "$TARGET_ABI" == armeabi-v7a ]; then
|
|
||||||
CROSS_PREFIX=armv7a-linux-androideabi
|
|
||||||
CFLAGS="-mthumb"
|
|
||||||
CXXFLAGS="-mthumb"
|
|
||||||
elif [ "$TARGET_ABI" == arm64-v8a ]; then
|
|
||||||
CROSS_PREFIX=aarch64-linux-android
|
|
||||||
elif [ "$TARGET_ABI" == x86 ]; then
|
|
||||||
CROSS_PREFIX=i686-linux-android
|
|
||||||
CFLAGS="-mssse3 -mfpmath=sse"
|
|
||||||
CXXFLAGS="-mssse3 -mfpmath=sse"
|
|
||||||
elif [ "$TARGET_ABI" == x86_64 ]; then
|
|
||||||
CROSS_PREFIX=x86_64-linux-android
|
|
||||||
else
|
|
||||||
echo "Invalid ABI given"; return 1
|
|
||||||
fi
|
|
||||||
export CC=$CROSS_PREFIX$API-clang
|
|
||||||
export CXX=$CROSS_PREFIX$API-clang++
|
|
||||||
export AR=llvm-ar
|
|
||||||
export RANLIB=llvm-ranlib
|
|
||||||
export CFLAGS="-fPIC ${CFLAGS}"
|
|
||||||
export CXXFLAGS="-fPIC ${CXXFLAGS}"
|
|
||||||
|
|
||||||
CMAKE_FLAGS=(
|
|
||||||
"-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake"
|
|
||||||
"-DANDROID_ABI=$TARGET_ABI" "-DANDROID_NATIVE_API_LEVEL=$API"
|
|
||||||
"-DCMAKE_BUILD_TYPE=Release"
|
|
||||||
)
|
|
||||||
|
|
||||||
# make sure pkg-config doesn't interfere
|
|
||||||
export PKG_CONFIG=/bin/false
|
|
||||||
|
|
||||||
export MAKEFLAGS="-j$(nproc)"
|
|
||||||
}
|
|
||||||
|
|
||||||
_run_build () {
|
|
||||||
local abi=$1
|
|
||||||
irrdir=$PWD
|
|
||||||
|
|
||||||
mkdir -p $RUNNER_TEMP/src
|
|
||||||
cd $RUNNER_TEMP/src
|
|
||||||
srcdir=$PWD
|
|
||||||
[ -d irrlicht ] || ln -s $irrdir irrlicht
|
|
||||||
download
|
|
||||||
|
|
||||||
builddir=$RUNNER_TEMP/build/irrlicht-$abi
|
|
||||||
pkgdir=$RUNNER_TEMP/pkg/$abi/Irrlicht
|
|
||||||
rm -rf "$pkgdir"
|
|
||||||
mkdir -p "$builddir" "$pkgdir"
|
|
||||||
|
|
||||||
cd "$builddir"
|
|
||||||
build
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ $# -lt 1 ]; then
|
|
||||||
echo "Usage: ci-build-android.sh <ABI>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
_setup_toolchain $1
|
|
||||||
_run_build $1
|
|
|
@ -1,70 +0,0 @@
|
||||||
#!/bin/bash -e
|
|
||||||
topdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
||||||
|
|
||||||
[[ -z "$CC" || -z "$CXX" ]] && exit 255
|
|
||||||
variant=win32
|
|
||||||
[[ "$(basename "$CXX")" == "x86_64-"* ]] && variant=win64
|
|
||||||
with_sdl=0
|
|
||||||
[[ "$extras" == *"-sdl"* ]] && with_sdl=1
|
|
||||||
#with_gl3=0
|
|
||||||
#[[ "$extras" == *"-gl3"* ]] && with_gl3=1
|
|
||||||
|
|
||||||
libjpeg_version=3.0.1
|
|
||||||
libpng_version=1.6.40
|
|
||||||
sdl2_version=2.28.5
|
|
||||||
zlib_version=1.3.1
|
|
||||||
|
|
||||||
download () {
|
|
||||||
local url=$1
|
|
||||||
local filename=${url##*/}
|
|
||||||
local foldername=${filename%%[.-]*}
|
|
||||||
|
|
||||||
[ -d "./$foldername" ] && return 0
|
|
||||||
[ -e "$filename" ] || wget "$url" -O "$filename"
|
|
||||||
sha256sum -w -c <(grep -F "$filename" "$topdir/sha256sums.txt")
|
|
||||||
unzip -o "$filename" -d "$foldername"
|
|
||||||
}
|
|
||||||
|
|
||||||
libs=$PWD/libs
|
|
||||||
mkdir -p libs
|
|
||||||
pushd libs
|
|
||||||
libhost="http://minetest.kitsunemimi.pw"
|
|
||||||
download "$libhost/llvm/libjpeg-$libjpeg_version-$variant.zip"
|
|
||||||
download "$libhost/llvm/libpng-$libpng_version-$variant.zip"
|
|
||||||
[ $with_sdl -eq 1 ] && download "$libhost/llvm/sdl2-$sdl2_version-$variant.zip"
|
|
||||||
download "$libhost/llvm/zlib-$zlib_version-$variant.zip"
|
|
||||||
popd
|
|
||||||
|
|
||||||
tmp=(
|
|
||||||
-DCMAKE_SYSTEM_NAME=Windows \
|
|
||||||
-DPNG_LIBRARY=$libs/libpng/lib/libpng.dll.a \
|
|
||||||
-DPNG_PNG_INCLUDE_DIR=$libs/libpng/include \
|
|
||||||
-DJPEG_LIBRARY=$libs/libjpeg/lib/libjpeg.dll.a \
|
|
||||||
-DJPEG_INCLUDE_DIR=$libs/libjpeg/include \
|
|
||||||
-DZLIB_LIBRARY=$libs/zlib/lib/libz.dll.a \
|
|
||||||
-DZLIB_INCLUDE_DIR=$libs/zlib/include
|
|
||||||
)
|
|
||||||
if [ $with_sdl -eq 1 ]; then
|
|
||||||
tmp+=(
|
|
||||||
-DUSE_SDL2=ON
|
|
||||||
-DCMAKE_PREFIX_PATH=$libs/sdl2/lib/cmake
|
|
||||||
)
|
|
||||||
else
|
|
||||||
tmp+=(-DUSE_SDL2=OFF)
|
|
||||||
fi
|
|
||||||
#[ $with_gl3 -eq 1 ] && tmp+=(-DENABLE_OPENGL=OFF -DENABLE_OPENGL3=ON)
|
|
||||||
|
|
||||||
cmake . "${tmp[@]}"
|
|
||||||
make -j$(nproc)
|
|
||||||
|
|
||||||
if [ "$1" = "package" ]; then
|
|
||||||
make DESTDIR=$PWD/_install install
|
|
||||||
# strip library
|
|
||||||
"${CXX%-*}-strip" --strip-unneeded _install/usr/local/lib/*.dll
|
|
||||||
# bundle the DLLs that are specific to Irrlicht (kind of a hack)
|
|
||||||
shopt -s nullglob
|
|
||||||
cp -p $libs/*/bin/{libjpeg,libpng,SDL}*.dll _install/usr/local/lib/
|
|
||||||
# create a ZIP
|
|
||||||
(cd _install/usr/local; zip -9r "$OLDPWD/irrlicht-$variant$extras.zip" -- *)
|
|
||||||
fi
|
|
||||||
exit 0
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
topdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
||||||
|
|
||||||
name=llvm-mingw-20231128-ucrt-ubuntu-20.04-x86_64.tar.xz
|
|
||||||
wget "https://github.com/mstorsjo/llvm-mingw/releases/download/20231128/$name" -O "$name"
|
|
||||||
sha256sum -w -c <(grep -F "$name" "$topdir/sha256sums.txt")
|
|
||||||
sudo tar -xaf "$name" -C /usr --strip-components=1
|
|
||||||
rm -f "$name"
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue