3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "../constants.h" // BS, MAP_BLOCKSIZE
24 #include "../noise.h" // PseudoRandom, PcgRandom
25 #include "../threading/mutex_auto_lock.h"
35 return g_pcgrand.next();
38 void mysrand(unsigned int seed)
43 void myrand_bytes(void *out, size_t len)
45 g_pcgrand.bytes(out, len);
48 int myrand_range(int min, int max)
50 return g_pcgrand.range(min, max);
55 64-bit unaligned version of MurmurHash
57 u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
59 const u64 m = 0xc6a4a7935bd1e995ULL;
61 u64 h = seed ^ (len * m);
63 const u64 *data = (const u64 *)key;
64 const u64 *end = data + (len / 8);
68 memcpy(&k, data, sizeof(u64));
79 const unsigned char *data2 = (const unsigned char *)data;
81 case 7: h ^= (u64)data2[6] << 48;
82 case 6: h ^= (u64)data2[5] << 40;
83 case 5: h ^= (u64)data2[4] << 32;
84 case 4: h ^= (u64)data2[3] << 24;
85 case 3: h ^= (u64)data2[2] << 16;
86 case 2: h ^= (u64)data2[1] << 8;
87 case 1: h ^= (u64)data2[0];
99 blockpos_b: position of block in block coordinates
100 camera_pos: position of camera in nodes
101 camera_dir: an unit vector pointing to camera direction
103 distance_ptr: return location for distance from the camera
105 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
106 f32 camera_fov, f32 range, f32 *distance_ptr)
108 // Maximum radius of a block. The magic number is
109 // sqrt(3.0) / 2.0 in literal form.
110 const f32 block_max_radius = 0.866025403784 * MAP_BLOCKSIZE * BS;
112 v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE;
114 // Block center position
116 ((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS,
117 ((float)blockpos_nodes.Y + MAP_BLOCKSIZE/2) * BS,
118 ((float)blockpos_nodes.Z + MAP_BLOCKSIZE/2) * BS
121 // Block position relative to camera
122 v3f blockpos_relative = blockpos - camera_pos;
125 f32 d = MYMAX(0, blockpos_relative.getLength() - block_max_radius);
130 // If block is far away, it's not in sight
134 // If block is (nearly) touching the camera, don't
135 // bother validating further (that is, render it anyway)
139 // Adjust camera position, for purposes of computing the angle,
140 // such that a block that has any portion visible with the
141 // current camera position will have the center visible at the
143 f32 adjdist = block_max_radius / cos((M_PI - camera_fov) / 2);
145 // Block position relative to adjusted camera
146 v3f blockpos_adj = blockpos - (camera_pos - camera_dir * adjdist);
148 // Distance in camera direction (+=front, -=back)
149 f32 dforward = blockpos_adj.dotProduct(camera_dir);
151 // Cosine of the angle between the camera direction
152 // and the block direction (camera_dir is an unit vector)
153 f32 cosangle = dforward / blockpos_adj.getLength();
155 // If block is not in the field of view, skip it
156 // HOTFIX: use sligthly increased angle (+10%) to fix too agressive
157 // culling. Somebody have to find out whats wrong with the math here.
158 // Previous value: camera_fov / 2
159 if(cosangle < cos(camera_fov * 0.55))