From 1bc37d576ce790c1169c5f9996be7bbc8026db2c Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sun, 17 Jun 2012 01:29:13 +0300 Subject: Initially split utility.h to multiple files in util/ --- src/util/numeric.cpp | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 src/util/numeric.cpp (limited to 'src/util/numeric.cpp') diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp new file mode 100644 index 000000000..d082cdb76 --- /dev/null +++ b/src/util/numeric.cpp @@ -0,0 +1,202 @@ +/* +Minetest-c55 +Copyright (C) 2010-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "numeric.h" + +#include "log.h" +#include "constants.h" // BS, MAP_BLOCKSIZE +#include + +// Calculate the borders of a "d-radius" cube +void getFacePositions(core::list &list, u16 d) +{ + if(d == 0) + { + list.push_back(v3s16(0,0,0)); + return; + } + if(d == 1) + { + /* + This is an optimized sequence of coordinates. + */ + list.push_back(v3s16( 0, 1, 0)); // top + list.push_back(v3s16( 0, 0, 1)); // back + list.push_back(v3s16(-1, 0, 0)); // left + list.push_back(v3s16( 1, 0, 0)); // right + list.push_back(v3s16( 0, 0,-1)); // front + list.push_back(v3s16( 0,-1, 0)); // bottom + // 6 + list.push_back(v3s16(-1, 0, 1)); // back left + list.push_back(v3s16( 1, 0, 1)); // back right + list.push_back(v3s16(-1, 0,-1)); // front left + list.push_back(v3s16( 1, 0,-1)); // front right + list.push_back(v3s16(-1,-1, 0)); // bottom left + list.push_back(v3s16( 1,-1, 0)); // bottom right + list.push_back(v3s16( 0,-1, 1)); // bottom back + list.push_back(v3s16( 0,-1,-1)); // bottom front + list.push_back(v3s16(-1, 1, 0)); // top left + list.push_back(v3s16( 1, 1, 0)); // top right + list.push_back(v3s16( 0, 1, 1)); // top back + list.push_back(v3s16( 0, 1,-1)); // top front + // 18 + list.push_back(v3s16(-1, 1, 1)); // top back-left + list.push_back(v3s16( 1, 1, 1)); // top back-right + list.push_back(v3s16(-1, 1,-1)); // top front-left + list.push_back(v3s16( 1, 1,-1)); // top front-right + list.push_back(v3s16(-1,-1, 1)); // bottom back-left + list.push_back(v3s16( 1,-1, 1)); // bottom back-right + list.push_back(v3s16(-1,-1,-1)); // bottom front-left + list.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++) + { + list.push_back(v3s16(d,y,z)); + list.push_back(v3s16(-d,y,z)); + if(y != 0) + { + list.push_back(v3s16(d,-y,z)); + list.push_back(v3s16(-d,-y,z)); + } + } + // Back and front side, excluding borders + for(s16 x=-d+1; x<=d-1; x++) + { + list.push_back(v3s16(x,y,d)); + list.push_back(v3s16(x,y,-d)); + if(y != 0) + { + list.push_back(v3s16(x,-y,d)); + list.push_back(v3s16(x,-y,-d)); + } + } + } + + // Take the bottom and top face with borders + // -d MYRAND_MAX) + { + errorstream<<"WARNING: myrand_range: max-min > MYRAND_MAX"< max) + { + errorstream<<"WARNING: myrand_range: min > max"< range) + return false; + + // Maximum radius of a block + f32 block_max_radius = 0.5*1.44*1.44*MAP_BLOCKSIZE*BS; + + // If block is (nearly) touching the camera, don't + // bother validating further (that is, render it anyway) + if(d < block_max_radius) + return true; + + // Cosine of the angle between the camera direction + // and the block direction (camera_dir is an unit vector) + f32 cosangle = dforward / d; + + // Compensate for the size of the block + // (as the block has to be shown even if it's a bit off FOV) + // This is an estimate, plus an arbitary factor + cosangle += block_max_radius / d * 0.5; + + // If block is not in the field of view, skip it + if(cosangle < cos(camera_fov / 2)) + return false; + + return true; +} + -- cgit v1.2.3