1
0
Fork 0

Time constant move, relative planar

This commit is contained in:
May B. 2020-08-03 19:55:03 +02:00
parent f7b34f74f8
commit a05378c274
15 changed files with 86 additions and 80 deletions

View File

@ -16,7 +16,7 @@ in GeometryData
in VertexData
#endif
{
vec3 Position_worldspace;
vec3 Position_modelspace;
#ifdef BLEND
flat uint Materials[3];
vec3 MaterialRatio;
@ -71,9 +71,9 @@ void main() {
vec3 blendWeights = abs(vs.FaceNormal_modelspace);
blendWeights = blendWeights - plateauSize;
blendWeights = pow(max(blendWeights, 0), vec3(transitionSpeed));
vec2 UVx = vs.Position_worldspace.yz * texScale;
vec2 UVy = vs.Position_worldspace.zx * texScale;
vec2 UVz = vs.Position_worldspace.xy * texScale;
vec2 UVx = vs.Position_modelspace.yz * texScale;
vec2 UVy = vs.Position_modelspace.zx * texScale;
vec2 UVz = vs.Position_modelspace.xy * texScale;
vec3 tex = getTriTexture(TextureAtlas, UVx, UVy, UVz, blendWeights);
@ -95,7 +95,7 @@ void main() {
// Cheap planar
vec3 blendWeights = abs(vs.FaceNormal_modelspace);
vec3 nrm = normalize(pow(blendWeights, vec3(80)));
vec2 UV = (vec2(vs.Position_worldspace.xy * nrm.z) + vec2(vs.Position_worldspace.yz * nrm.x) + vec2(vs.Position_worldspace.zx * nrm.y)) * texScale;
vec2 UV = (vec2(vs.Position_modelspace.xy * nrm.z) + vec2(vs.Position_modelspace.yz * nrm.x) + vec2(vs.Position_modelspace.zx * nrm.y)) * texScale;
vec3 tex = getTexture(TextureAtlas, UV).rgb;
#ifdef PBR

View File

@ -5,7 +5,7 @@ layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
in VertexData {
vec3 Position_worldspace;
vec3 Position_modelspace;
flat uint Material;
vec3 FaceNormal_modelspace;
#ifdef PBR
@ -19,7 +19,7 @@ in VertexData {
} vs_in[];
out GeometryData {
vec3 Position_worldspace;
vec3 Position_modelspace;
flat uint Materials[3];
vec3 MaterialRatio;
vec3 FaceNormal_modelspace;
@ -37,7 +37,7 @@ void main() {
for(int i = 0; i < gl_in.length(); i++) {
gl_Position = gl_in[i].gl_Position;
gs.Position_worldspace = vs_in[i].Position_worldspace;
gs.Position_modelspace = vs_in[i].Position_modelspace;
gs.FaceNormal_modelspace = vs_in[i].FaceNormal_modelspace;
gs.FaceNormal_worldspace = vs_in[i].FaceNormal_worldspace;

View File

@ -5,7 +5,7 @@ layout(location = 1) in uint Material_model;
layout(location = 2) in vec3 Normal_modelspace;
out VertexData {
vec3 Position_worldspace;
vec3 Position_modelspace;
flat uint Material;
vec3 FaceNormal_modelspace;
#ifdef PBR
@ -27,10 +27,11 @@ uniform float FogDepth;
void main(){
gl_Position = MVP * vec4(Position_modelspace, 1);
vs.Position_worldspace = (Model * vec4(Position_modelspace,1)).xyz;
vs.Position_modelspace = Position_modelspace;
vec3 Position_worldspace = (Model * vec4(Position_modelspace,1)).xyz;
#ifdef FOG
vs.Depth = length((View * vec4(vs.Position_worldspace,1)).xyz) / FogDepth;
vs.Depth = length((View * vec4(Position_worldspace,1)).xyz) / FogDepth;
#endif
vs.Material = Material_model;

View File

@ -12,8 +12,8 @@ namespace contouring {
while (it_a != buffers.end()) { // Remove out of range buffers
if (const auto area = areas.find(it_a->first); area != areas.end()) {
//Update
const auto& offset = it_a->second.first = area->second->getOffset();
const auto center = glm::divide(pos - offset);
it_a->second.first = area->second->getOffset();
const auto center = glm::divide(pos - it_a->second.first.as_voxel());
auto &bfs = it_a->second.second;
auto it = bfs.begin();
while(it != bfs.end()) {
@ -62,7 +62,7 @@ namespace contouring {
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(1.f / density));
for (const auto [_, area] : buffers) {
for (const auto [pos, buffer] : area.second) {
const glm::vec3 fPos = glm::vec3(area.first + glm::multiply(pos) - offset * glm::llvec3(density)) / glm::vec3(density);
const glm::vec3 fPos = (glm::vec3(area.first.raw_as_long() + glm::multiply(pos) - offset * glm::llvec3(density)) + area.first.offset) / glm::vec3(density);
if (buffer != NULL && (!frustum.has_value() || frustum.value().contains(geometry::Box::fromMin(fPos, glm::vec3(CHUNK_LENGTH / (float)density)))))
out.emplace_back(glm::translate(scaling, fPos * (float)density), buffer);
}}

View File

@ -23,7 +23,7 @@ namespace contouring {
size_t clear(const voxel_pos &, const world::area_map &areas);
//MAYBE: store position copy
robin_hood::unordered_flat_map<area_id, robin_hood::pair<voxel_pos, robin_hood::unordered_flat_map<chunk_pos, buffer::Abstract *>>> buffers;
robin_hood::unordered_flat_map<area_id, robin_hood::pair<area_pos, robin_hood::unordered_flat_map<chunk_pos, buffer::Abstract *>>> buffers;
int loadDistance = 3;
int keepDistance = 4;

View File

@ -13,14 +13,7 @@ void Camera::updateProjection() {
ProjectionMatrix = glm::perspective(o.fov, RATIO, o.near, o.far);
}
void Camera::update(bool captureMouse, bool captureKeys) {
// glfwGetTime is called only once, the first time this function is called
static double lastTime = glfwGetTime();
// Compute time difference between current and last frame
double currentTime = glfwGetTime();
float deltaTime = float(currentTime - lastTime);
void Camera::update(bool captureMouse, bool captureKeys, float deltaTime) {
// Get mouse position
if(captureMouse) {
int viewportX, viewportY;
@ -91,7 +84,4 @@ void Camera::update(bool captureMouse, bool captureKeys) {
Position.offset + direction, // and looks here : at the same position, plus "direction"
up // Head is up (set to 0,-1,0 to look upside-down)
);
// For the next frame, the "last time" will be "now"
lastTime = currentTime;
}

View File

@ -24,7 +24,7 @@ public:
Camera(GLFWwindow*, const InputMap&, const options&);
~Camera();
void update(bool captureMouse, bool captureKeys);
void update(bool captureMouse, bool captureKeys, float deltaTime);
void setOptions(const options &options) {
o = options;
updateProjection();

16
src/data/glm.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "glm.hpp"
#include "math.hpp"
using namespace glm;
ifvec3::ifvec3(const llvec3 &pos, int density) : raw(divide(pos, uvec3(IDX_LENGTH2 * density))), offset(0) {}
llvec3 ifvec3::raw_as_long() const {
return llvec3(raw) * llvec3(IDX_LENGTH2);
}
llvec3 ifvec3::as_voxel(int density) const {
return raw_as_long() * llvec3(density) + llvec3(offset * vec3(density));
}
void ifvec3::center() {
const auto diff = divide(offset, uvec3(IDX_LENGTH2));
raw += diff;
offset -= diff * static_cast<long>(IDX_LENGTH2);
}

View File

@ -12,4 +12,29 @@ namespace glm {
const auto IDX_LENGTH2 = IDX_LENGTH * IDX_LENGTH;
const auto IDX_SIZE = IDX_LENGTH2 * IDX_LENGTH;
using idx = glm::u16;
/// Combination of ivec3 and vec3 as a big and high precision
/// Scale to IDX_LENGTH2
struct ifvec3 {
using raw_t = glm::ivec3;
using offset_t = glm::vec3;
ifvec3(): raw(0), offset(0) { }
ifvec3(const raw_t &raw, const offset_t &offset, bool recenter = true) : raw(raw), offset(offset) {
if(recenter) center();
}
ifvec3(const glm::llvec3 &pos, int density = 1);
raw_t raw;
offset_t offset;
glm::llvec3 as_voxel(int density = 1) const;
void center();
glm::llvec3 raw_as_long() const;
glm::dvec3 as_double() const;
inline ifvec3 operator+(const offset_t& v) const { return ifvec3(raw, offset + v); }
inline ifvec3 operator/(int i) const { return ifvec3(raw / i, offset / (i * 1.f), false); }
inline ifvec3 operator*(int i) const { return ifvec3(raw * i, offset * (i * 1.f)); }
};
}

View File

@ -89,11 +89,13 @@ int main(int /*unused*/, char */*unused*/[]){
const double startTime = glfwGetTime();
{ // Update
rmt_ScopedCPUSample(Update, 0);
static double lastTime = glfwGetTime();
const double partTime = glfwGetTime();
const float deltaTime = float(partTime - lastTime);
inputs.toggle(state.capture_mouse, Input::Mouse);
inputs.toggle(options.show_debug_menu, Input::Debug);
camera.update(state.capture_mouse, !UI::isFocus());
camera.update(state.capture_mouse, !UI::isFocus(), deltaTime);
renderer->lookFrom(camera);
state.position = camera.getPosition();
@ -104,9 +106,10 @@ int main(int /*unused*/, char */*unused*/[]){
else if (inputs.isPressing(Mouse::Right))
world.setCube(state.look_at.value().pos, world::Voxel(options.tool.material, world::Voxel::DENSITY_MAX), options.tool.radius);
}
world.update((state.position * options.voxel_density).as_voxel(), reports.world);
world.update((state.position * options.voxel_density).as_voxel(), deltaTime, reports.world);
inputs.saveKeys();
reports.main.update.push((glfwGetTime() - partTime) * 1000);
lastTime = partTime;
}
{

View File

@ -32,18 +32,19 @@ namespace world {
using regions_t = robin_hood::unordered_map<region_pos, std::shared_ptr<Region>>;
/// radius: size in chunk (length = radius * 2 + 1)
Area(const voxel_pos& center, int radius, int seed = 42): center(center), chunks(radius), generator(seed) { }
Area(const area_pos& center, int radius, int seed = 42): center(center), chunks(radius), generator(seed) { }
inline const voxel_pos &getOffset() const { return center; }
inline const area_pos &getOffset() const { return center; }
inline geometry::IBox getBounding() const {
return geometry::IBox(center - voxel_pos(CHUNK_LENGTH * (chunks.getRadius() - 1)),
center + voxel_pos(CHUNK_LENGTH * chunks.getRadius()));
const auto c = center.as_voxel();
return geometry::IBox(c - voxel_pos(CHUNK_LENGTH * (chunks.getRadius() - 1)),
c + voxel_pos(CHUNK_LENGTH * chunks.getRadius()));
}
/// Move offset return if chunk_change
constexpr bool inline move(const voxel_pos &offset) {
const auto prev = glm::divide(center);
center += offset;
return prev != glm::divide(center);
bool inline move(const area_pos::offset_t &offset) {
const auto prev = glm::divide(center.as_voxel());
center = center + offset;
return prev != glm::divide(center.as_voxel());
}
inline const ChunkContainer &getChunks() const { return chunks; }
@ -55,7 +56,7 @@ namespace world {
inline Generator &getGenerator() { return generator; }
private:
voxel_pos center;
area_pos center;
//TODO: rotation
ChunkContainer chunks;

View File

@ -21,8 +21,8 @@ Universe::Universe(const Universe::options &options): dicts("content/zstd.dict"
running = true;
std::filesystem::create_directories(folderPath);
areas.emplace(MAIN_AREA, std::make_shared<Area>(glm::multiply(chunk_pos(1 << 8, 0, 0)), 1 << 20));
areas.emplace(2, std::make_shared<Area>(voxel_pos(0), 1 << 20));
//areas.emplace(MAIN_AREA, std::make_shared<Area>(area_pos(glm::multiply(chunk_pos(1 << 8, 0, 0))), 1 << 20));
areas.emplace(2, std::make_shared<Area>(area_pos(voxel_pos(0)), 1 << 20));
// Load workers
for (size_t i = 0; i < 4; i++) {
@ -106,11 +106,11 @@ Universe::~Universe() {
LOG_D("Universe disappeared");
}
void Universe::update(const voxel_pos& pos, Universe::report& rep) {
void Universe::update(const voxel_pos& pos, float deltaTime, Universe::report& rep) {
rmt_ScopedCPUSample(Universe, 0);
const chunk_pos newPos = glm::divide(pos);
const auto chunkChange = last_pos != newPos;
last_pos = newPos;
rmt_ScopedCPUSample(Universe, 0);
{ // Update alive areas
rmt_ScopedCPUSample(Update, 0);
@ -121,8 +121,8 @@ void Universe::update(const voxel_pos& pos, Universe::report& rep) {
auto it = areas.begin();
while (it != areas.end()) {
rmt_ScopedCPUSample(Area, 0);
const bool chunkChangeArea = (it->first == 2 && it->second->move(voxel_pos(1, 0, 0))) || chunkChange; // TODO: area.velocity
const chunk_pos diff = glm::divide(pos - it->second->getOffset());
const bool chunkChangeArea = (it->first == 2 && it->second->move(glm::vec3(deltaTime))) || chunkChange; // TODO: area.velocity
const chunk_pos diff = glm::divide(pos - it->second->getOffset().as_voxel());
auto &chunks = it->second->setChunks();
if (glm::length2(diff) > glm::pow2(keepDistance + it->second->getChunks().getRadius())) {
auto it_c = chunks.begin();
@ -202,7 +202,7 @@ void Universe::update(const voxel_pos& pos, Universe::report& rep) {
if (const auto it = areas.find(loaded.first.first); it != areas.end()) {
auto &chunks = it->second->setChunks();
chunks.emplace(loaded.first.second, loaded.second);
const chunk_pos diff = glm::divide(pos - it->second->getOffset());
const chunk_pos diff = glm::divide(pos - it->second->getOffset().as_voxel());
contouring->onUpdate(loaded.first, diff, chunks, Faces::All);
}
}
@ -219,13 +219,14 @@ void Universe::setContouring(const std::shared_ptr<contouring::Abstract>& ct) {
}
std::optional<Universe::ray_target> Universe::raycast(const Ray &ray) const {
//MAYBE: ray + offset to get float precision
std::vector<voxel_pos> points;
ray.grid(points);
std::optional<Universe::ray_target> target = std::nullopt;
size_t dist = points.size();
for(auto& area: areas) {
if(ray.intersect(area.second->getBounding()) != IBox::ContainmentType::Disjoint) {
const auto &offset = area.second->getOffset();
const auto &offset = area.second->getOffset().as_voxel();
const auto &chunks = area.second->getChunks();
std::shared_ptr<Chunk> chunk = nullptr;
chunk_pos chunk_vec(INT_MAX);

View File

@ -48,7 +48,7 @@ namespace world {
~Universe();
/// Update physics and contouring
void update(const voxel_pos &pos, report &rep);
void update(const voxel_pos &pos, float deltaTime, report &rep);
/// Apply new options
void setOptions(const options &);

View File

@ -1,15 +0,0 @@
#include "position.h"
#include "../data/math.hpp"
camera_pos::camera_pos(const voxel_pos &pos, int density): raw(glm::divide(pos, glm::uvec3(REGION_LENGTH * CHUNK_LENGTH * density))), offset(0) { }
glm::llvec3 camera_pos::raw_as_long() const {
return glm::llvec3(raw) * glm::llvec3(REGION_LENGTH * CHUNK_LENGTH);
}
voxel_pos camera_pos::as_voxel(int density) const {
return raw_as_long() * glm::llvec3(density) + voxel_pos(offset * glm::vec3(density));
}
void camera_pos::center() {
const auto diff = glm::divide(offset, glm::uvec3(REGION_LENGTH * CHUNK_LENGTH));
raw += diff;
offset -= diff * static_cast<long>(REGION_LENGTH * CHUNK_LENGTH);
}

View File

@ -44,23 +44,7 @@ struct area_hash {
return h1 ^ (h2 << 1);
}
};
using area_pos = glm::ifvec3;
using entity_id = uint64_t;
struct camera_pos {
using raw_t = region_pos;
using offset_t = glm::vec3;
camera_pos(const raw_t &raw, const offset_t &offset) : raw(raw), offset(offset){};
camera_pos(const voxel_pos& pos, int density);
raw_t raw;
offset_t offset;
voxel_pos as_voxel(int density = 1) const;
void center();
glm::llvec3 raw_as_long() const;
glm::dvec3 as_double() const;
inline camera_pos operator/(int i) const { return camera_pos(raw / i, offset / (i * 1.f)); }
inline camera_pos operator*(int i) const { return camera_pos(raw * i, offset * (i * 1.f)); }
};
using camera_pos = glm::ifvec3;