1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-22 17:18:39 +00:00

Clean up numeric.h and split FacePositionCache from it

I also optiized FacePositionCache a bit: I removed a map
lookup and vector copy from both branches of getFacePosition.
This commit is contained in:
ShadowNinja 2015-07-06 12:53:30 -04:00
parent b6f4a9c7e1
commit 77597c4ff3
17 changed files with 205 additions and 157 deletions

View file

@ -20,14 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef BASICMACROS_HEADER
#define BASICMACROS_HEADER
#include <algorithm>
#define ARRLEN(x) (sizeof(x) / sizeof((x)[0]))
#define MYMIN(a, b) ((a) < (b) ? (a) : (b))
#define MYMAX(a, b) ((a) > (b) ? (a) : (b))
// Requires <algorithm>
#define CONTAINS(c, v) (std::find((c).begin(), (c).end(), (v)) != (c).end())
// To disable copy constructors and assignment operations for some class

View file

@ -24,100 +24,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "../noise.h" // PseudoRandom, PcgRandom
#include "../threading/mutex_auto_lock.h"
#include <string.h>
#include <iostream>
UNORDERED_MAP<u16, std::vector<v3s16> > FacePositionCache::m_cache;
Mutex FacePositionCache::m_cache_mutex;
// Calculate the borders of a "d-radius" cube
// TODO: Make it work without mutex and data races, probably thread-local
std::vector<v3s16> FacePositionCache::getFacePositions(u16 d)
{
MutexAutoLock cachelock(m_cache_mutex);
if (m_cache.find(d) != m_cache.end())
return m_cache[d];
generateFacePosition(d);
return m_cache[d];
}
void FacePositionCache::generateFacePosition(u16 d)
{
m_cache[d] = std::vector<v3s16>();
if(d == 0) {
m_cache[d].push_back(v3s16(0,0,0));
return;
}
if(d == 1) {
/*
This is an optimized sequence of coordinates.
*/
m_cache[d].push_back(v3s16( 0, 1, 0)); // top
m_cache[d].push_back(v3s16( 0, 0, 1)); // back
m_cache[d].push_back(v3s16(-1, 0, 0)); // left
m_cache[d].push_back(v3s16( 1, 0, 0)); // right
m_cache[d].push_back(v3s16( 0, 0,-1)); // front
m_cache[d].push_back(v3s16( 0,-1, 0)); // bottom
// 6
m_cache[d].push_back(v3s16(-1, 0, 1)); // back left
m_cache[d].push_back(v3s16( 1, 0, 1)); // back right
m_cache[d].push_back(v3s16(-1, 0,-1)); // front left
m_cache[d].push_back(v3s16( 1, 0,-1)); // front right
m_cache[d].push_back(v3s16(-1,-1, 0)); // bottom left
m_cache[d].push_back(v3s16( 1,-1, 0)); // bottom right
m_cache[d].push_back(v3s16( 0,-1, 1)); // bottom back
m_cache[d].push_back(v3s16( 0,-1,-1)); // bottom front
m_cache[d].push_back(v3s16(-1, 1, 0)); // top left
m_cache[d].push_back(v3s16( 1, 1, 0)); // top right
m_cache[d].push_back(v3s16( 0, 1, 1)); // top back
m_cache[d].push_back(v3s16( 0, 1,-1)); // top front
// 18
m_cache[d].push_back(v3s16(-1, 1, 1)); // top back-left
m_cache[d].push_back(v3s16( 1, 1, 1)); // top back-right
m_cache[d].push_back(v3s16(-1, 1,-1)); // top front-left
m_cache[d].push_back(v3s16( 1, 1,-1)); // top front-right
m_cache[d].push_back(v3s16(-1,-1, 1)); // bottom back-left
m_cache[d].push_back(v3s16( 1,-1, 1)); // bottom back-right
m_cache[d].push_back(v3s16(-1,-1,-1)); // bottom front-left
m_cache[d].push_back(v3s16( 1,-1,-1)); // bottom front-right
// 26
return;
}
// Take blocks in all sides, starting from y=0 and going +-y
for(s16 y=0; y<=d-1; y++) {
// Left and right side, including borders
for(s16 z=-d; z<=d; z++) {
m_cache[d].push_back(v3s16(d,y,z));
m_cache[d].push_back(v3s16(-d,y,z));
if(y != 0) {
m_cache[d].push_back(v3s16(d,-y,z));
m_cache[d].push_back(v3s16(-d,-y,z));
}
}
// Back and front side, excluding borders
for(s16 x=-d+1; x<=d-1; x++) {
m_cache[d].push_back(v3s16(x,y,d));
m_cache[d].push_back(v3s16(x,y,-d));
if(y != 0) {
m_cache[d].push_back(v3s16(x,-y,d));
m_cache[d].push_back(v3s16(x,-y,-d));
}
}
}
// Take the bottom and top face with borders
// -d<x<d, y=+-d, -d<z<d
for(s16 x=-d; x<=d; x++)
for(s16 z=-d; z<=d; z++) {
m_cache[d].push_back(v3s16(x,-d,z));
m_cache[d].push_back(v3s16(x,d,z));
}
}
/*
myrand
*/
// myrand
PcgRandom g_pcgrand;

View file

@ -26,28 +26,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "../irr_v3d.h"
#include "../irr_aabb3d.h"
#include "../threading/mutex.h"
#include "cpp11_container.h"
#include <list>
#include <vector>
#define rangelim(d, min, max) ((d) < (min) ? (min) : ((d) > (max) ? (max) : (d)))
#define myfloor(x) ((x) > 0.0 ? (int)(x) : (int)(x) - 1)
// The naive swap performs better than the xor version
#define SWAP(t, x, y) do { \
t temp = x; \
x = y; \
y = temp; \
} while (0)
/*
* This class permits to cache getFacePosition call results
* This reduces CPU usage and vector calls
*/
class FacePositionCache
{
public:
static std::vector<v3s16> getFacePositions(u16 d);
private:
static void generateFacePosition(u16 d);
static UNORDERED_MAP<u16, std::vector<v3s16> > m_cache;
static Mutex m_cache_mutex;
};
inline s16 getContainerPos(s16 p, s16 d)
{
return (p>=0 ? p : p-d+1) / d;
return (p >= 0 ? p : p - d + 1) / d;
}
inline v2s16 getContainerPos(v2s16 p, s16 d)
@ -130,16 +122,6 @@ inline bool isInArea(v3s16 p, v3s16 d)
);
}
#define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
#define myfloor(x) ((x) > 0.0 ? (int)(x) : (int)(x) - 1)
// The naive swap performs better than the xor version
#define SWAP(t, x, y) do { \
t temp = x; \
x = y; \
y = temp; \
} while (0)
inline void sortBoxVerticies(v3s16 &p1, v3s16 &p2) {
if (p1.X > p2.X)
SWAP(s16, p1.X, p2.X);
@ -266,11 +248,10 @@ inline s32 myround(f32 f)
*/
inline v3s16 floatToInt(v3f p, f32 d)
{
v3s16 p2(
(p.X + (p.X>0 ? d/2 : -d/2))/d,
(p.Y + (p.Y>0 ? d/2 : -d/2))/d,
(p.Z + (p.Z>0 ? d/2 : -d/2))/d);
return p2;
return v3s16(
(p.X + (p.X > 0 ? d / 2 : -d / 2)) / d,
(p.Y + (p.Y > 0 ? d / 2 : -d / 2)) / d,
(p.Z + (p.Z > 0 ? d / 2 : -d / 2)) / d);
}
/*
@ -278,34 +259,31 @@ inline v3s16 floatToInt(v3f p, f32 d)
*/
inline v3f intToFloat(v3s16 p, f32 d)
{
v3f p2(
return v3f(
(f32)p.X * d,
(f32)p.Y * d,
(f32)p.Z * d
);
return p2;
}
// Random helper. Usually d=BS
inline aabb3f getNodeBox(v3s16 p, float d)
{
return aabb3f(
(float)p.X * d - 0.5*d,
(float)p.Y * d - 0.5*d,
(float)p.Z * d - 0.5*d,
(float)p.X * d + 0.5*d,
(float)p.Y * d + 0.5*d,
(float)p.Z * d + 0.5*d
(float)p.X * d - 0.5 * d,
(float)p.Y * d - 0.5 * d,
(float)p.Z * d - 0.5 * d,
(float)p.X * d + 0.5 * d,
(float)p.Y * d + 0.5 * d,
(float)p.Z * d + 0.5 * d
);
}
class IntervalLimiter
{
public:
IntervalLimiter():
m_accumulator(0)
{
}
IntervalLimiter() : m_accumulator(0) {}
/*
dtime: time from last call to this method
wanted_interval: interval wanted
@ -316,15 +294,17 @@ public:
bool step(float dtime, float wanted_interval)
{
m_accumulator += dtime;
if(m_accumulator < wanted_interval)
if (m_accumulator < wanted_interval)
return false;
m_accumulator -= wanted_interval;
return true;
}
protected:
private:
float m_accumulator;
};
/*
Splits a list into "pages". For example, the list [1,2,3,4,5] split
into two pages would be [1,2,3],[4,5]. This function computes the
@ -340,29 +320,21 @@ protected:
*/
inline void paging(u32 length, u32 page, u32 pagecount, u32 &minindex, u32 &maxindex)
{
if(length < 1 || pagecount < 1 || page < 1 || page > pagecount)
{
if (length < 1 || pagecount < 1 || page < 1 || page > pagecount) {
// Special cases or invalid parameters
minindex = maxindex = 0;
}
else if(pagecount <= length)
{
} else if(pagecount <= length) {
// Less pages than entries in the list:
// Each page contains at least one entry
minindex = (length * (page-1) + (pagecount-1)) / pagecount;
maxindex = (length * page + (pagecount-1)) / pagecount;
}
else
{
} else {
// More pages than entries in the list:
// Make sure the empty pages are at the end
if(page < length)
{
if (page < length) {
minindex = page-1;
maxindex = page;
}
else
{
} else {
minindex = 0;
maxindex = 0;
}
@ -371,14 +343,14 @@ inline void paging(u32 length, u32 page, u32 pagecount, u32 &minindex, u32 &maxi
inline float cycle_shift(float value, float by = 0, float max = 1)
{
if (value + by < 0) return max + by + value;
if (value + by < 0) return value + by + max;
if (value + by > max) return value + by - max;
return value + by;
}
inline bool is_power_of_two(u32 n)
{
return n != 0 && (n & (n-1)) == 0;
return n != 0 && (n & (n - 1)) == 0;
}
// Compute next-higher power of 2 efficiently, e.g. for power-of-2 texture sizes.

View file

@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "hex.h"
#include "../porting.h"
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <map>