Time constant move, relative planar
This commit is contained in:
parent
f7b34f74f8
commit
a05378c274
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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)); }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 &);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue