terrain tesselation; fixed group undo

This commit is contained in:
Mikulas Florek 2022-05-08 12:46:23 +02:00
parent e5d1f7a818
commit 61e978114b
7 changed files with 59 additions and 23 deletions

View file

@ -2787,7 +2787,7 @@ public:
if (equalStrings(m_undo_stack[m_undo_index]->getType(), "end_group"))
{
--m_undo_index;
while (equalStrings(m_undo_stack[m_undo_index]->getType(), "begin_group"))
while (!equalStrings(m_undo_stack[m_undo_index]->getType(), "begin_group"))
{
m_undo_stack[m_undo_index]->undo();
--m_undo_index;

View file

@ -48,6 +48,9 @@ struct LUMIX_ENGINE_API IVec4 {
IVec4(i32 v) : x(v), y(v), z(v), w(v) {}
IVec4(const IVec2& a, const IVec2& b) : x(a.x), y(a.y), z(b.x), w(b.y) {}
void operator += (const IVec4& rhs);
IVec2 xy() const { return {x,y}; }
IVec2 zw() const { return {z,w}; }
i32 x, y, z, w;
};

View file

@ -4446,14 +4446,15 @@ struct PipelineImpl final : Pipeline
const Vec3 ref_pos = inst.rot.conjugated().rotate(-inst.ref_pos);
IVec4 prev_from_to;
float s = inst.scale.x;
float s = inst.scale.x / terrain->m_tesselation;
bool first = true;
for (;;) {
// round
IVec2 from = IVec2((ref_pos.xz() + Vec2(0.5f * s)) / float(s)) - IVec2(32);
IVec2 from = IVec2((ref_pos.xz() + Vec2(0.5f * s)) / float(s)) - IVec2(terrain->m_base_grid_res / 2);
from.x = from.x & ~1;
from.y = from.y & ~1;
IVec2 to = from + IVec2(64);
IVec2 to = from + IVec2(terrain->m_base_grid_res);
// clamp
quad.from_to_sup = IVec4(from, to);

View file

@ -48,20 +48,6 @@ static const ComponentType REFLECTION_PROBE_TYPE = reflection::getComponentType(
static const ComponentType SPLINE_GEOMETRY_TYPE = reflection::getComponentType("spline_geometry");
static const ComponentType FUR_TYPE = reflection::getComponentType("fur");
enum class RenderSceneVersion : i32
{
DECAL_UV_SCALE,
CURVE_DECALS,
AUTODESTROY_EMITTER,
SMALLER_MODEL_INSTANCES,
INSTANCED_MODEL,
SPLINES,
SPLINES_VERTEX_COLORS,
PROCEDURAL_GEOMETRY_PRIMITIVE_TYPE,
PROCEDURAL_GEOMETRY_INDEX_BUFFER,
LATEST
};
struct BoneAttachment
{
@ -1159,7 +1145,7 @@ struct RenderSceneImpl final : RenderScene {
}
}
void deserializeTerrains(InputMemoryStream& serializer, const EntityMap& entity_map) {
void deserializeTerrains(InputMemoryStream& serializer, const EntityMap& entity_map, i32 version) {
i32 size = 0;
serializer.read(size);
for (int i = 0; i < size; ++i)
@ -1168,7 +1154,7 @@ struct RenderSceneImpl final : RenderScene {
serializer.read(entity);
entity = entity_map.get(entity);
auto* terrain = LUMIX_NEW(m_allocator, Terrain)(m_renderer, entity, *this, m_allocator);
terrain->deserialize(entity, serializer, m_universe, *this);
terrain->deserialize(entity, serializer, m_universe, *this, version);
m_terrains.insert(entity, terrain);
}
}
@ -1184,7 +1170,7 @@ struct RenderSceneImpl final : RenderScene {
deserializeModelInstancesOld(serializer, entity_map);
}
deserializeLights(serializer, entity_map);
deserializeTerrains(serializer, entity_map);
deserializeTerrains(serializer, entity_map, version);
deserializeParticleEmitters(serializer, entity_map, version);
deserializeBoneAttachments(serializer, entity_map);
deserializeEnvironmentProbes(serializer, entity_map);
@ -1791,6 +1777,21 @@ struct RenderSceneImpl final : RenderScene {
float getTerrainXZScale(EntityRef entity) override { return m_terrains[entity]->getXZScale(); }
void setTerrainBaseGridResolution(EntityRef entity, u32 value) override {
m_terrains[entity]->m_base_grid_res = (maximum(8, value) + 1) & ~1;
}
u32 getTerrainBaseGridResolution(EntityRef entity) override {
return m_terrains[entity]->m_base_grid_res;
}
void setTerrainTesselation(EntityRef entity, u32 value) override {
m_terrains[entity]->m_tesselation = maximum(1, value);
}
u32 getTerrainTesselation(EntityRef entity) override {
return m_terrains[entity]->m_tesselation;
}
void setTerrainYScale(EntityRef entity, float scale) override
{
@ -3494,6 +3495,8 @@ void RenderScene::reflect() {
.LUMIX_PROP(TerrainMaterialPath, "Material").resourceAttribute(Material::TYPE)
.LUMIX_PROP(TerrainXZScale, "XZ scale").minAttribute(0)
.LUMIX_PROP(TerrainYScale, "Height scale").minAttribute(0)
.LUMIX_PROP(TerrainTesselation, "Tesselation").minAttribute(1)
.LUMIX_PROP(TerrainBaseGridResolution, "Grid resolution").minAttribute(8)
.begin_array<&RenderScene::getGrassCount, &RenderScene::addGrass, &RenderScene::removeGrass>("grass")
.LUMIX_PROP(GrassPath, "Mesh").resourceAttribute(Model::TYPE)
.LUMIX_PROP(GrassDistance, "Distance").minAttribute(1)

View file

@ -277,6 +277,21 @@ struct FurComponent {
bool enabled = true;
};
enum class RenderSceneVersion : i32 {
DECAL_UV_SCALE,
CURVE_DECALS,
AUTODESTROY_EMITTER,
SMALLER_MODEL_INSTANCES,
INSTANCED_MODEL,
SPLINES,
SPLINES_VERTEX_COLORS,
PROCEDURAL_GEOMETRY_PRIMITIVE_TYPE,
PROCEDURAL_GEOMETRY_INDEX_BUFFER,
TESSELATED_TERRAIN,
LATEST
};
struct LUMIX_RENDERER_API RenderScene : IScene
{
static UniquePtr<RenderScene> createInstance(Renderer& renderer,
@ -401,6 +416,10 @@ struct LUMIX_RENDERER_API RenderScene : IScene
virtual Material* getTerrainMaterial(EntityRef entity) = 0;
virtual void setTerrainXZScale(EntityRef entity, float scale) = 0;
virtual float getTerrainXZScale(EntityRef entity) = 0;
virtual void setTerrainTesselation(EntityRef entity, u32 value) = 0;
virtual u32 getTerrainTesselation(EntityRef entity) = 0;
virtual void setTerrainBaseGridResolution(EntityRef entity, u32 value) = 0;
virtual u32 getTerrainBaseGridResolution(EntityRef entity) = 0;
virtual void setTerrainYScale(EntityRef entity, float scale) = 0;
virtual float getTerrainYScale(EntityRef entity) = 0;
virtual Vec2 getTerrainSize(EntityRef entity) = 0;

View file

@ -158,6 +158,8 @@ Terrain::Terrain(Renderer& renderer, EntityPtr entity, RenderScene& scene, IAllo
, m_allocator(allocator)
, m_grass_types(m_allocator)
, m_renderer(renderer)
, m_tesselation(1)
, m_base_grid_res(64)
{
}
@ -324,13 +326,17 @@ void Terrain::setMaterial(Material* material)
}
}
void Terrain::deserialize(EntityRef entity, InputMemoryStream& serializer, Universe& universe, RenderScene& scene)
void Terrain::deserialize(EntityRef entity, InputMemoryStream& serializer, Universe& universe, RenderScene& scene, i32 version)
{
m_entity = entity;
serializer.read(m_layer_mask);
const char* path = serializer.readString();
serializer.read(m_scale.x);
serializer.read(m_scale.y);
if (version > (i32)RenderSceneVersion::TESSELATED_TERRAIN) {
serializer.read(m_tesselation);
serializer.read(m_base_grid_res);
}
m_scale.z = m_scale.x;
setMaterial(scene.getEngine().getResourceManager().load<Material>(Path(path)));
i32 count;
@ -363,6 +369,8 @@ void Terrain::serialize(OutputMemoryStream& serializer)
serializer.writeString(m_material ? m_material->getPath().c_str() : "");
serializer.write(m_scale.x);
serializer.write(m_scale.y);
serializer.write(m_tesselation);
serializer.write(m_base_grid_res);
serializer.write((i32)m_grass_types.size());
for(int i = 0; i < m_grass_types.size(); ++i)
{

View file

@ -101,7 +101,7 @@ struct Terrain {
RayCastModelHit castRay(const DVec3& origin, const Vec3& dir);
void serialize(OutputMemoryStream& serializer);
void deserialize(EntityRef entity, InputMemoryStream& serializer, Universe& universe, RenderScene& scene);
void deserialize(EntityRef entity, InputMemoryStream& serializer, Universe& universe, RenderScene& scene, i32 version);
void addGrassType(int index);
void removeGrassType(int index);
@ -112,6 +112,8 @@ struct Terrain {
i32 m_width;
i32 m_height;
i64 m_layer_mask;
u32 m_tesselation;
u32 m_base_grid_res;
Vec3 m_scale;
EntityRef m_entity;
Material* m_material;