layer strength
This commit is contained in:
@@ -295,7 +295,7 @@ public:
|
||||
QueryRangeNode(int32_t mnX, int32_t mnY, int32_t mxX, int32_t mxY, int32_t id)
|
||||
: minX(mnX), minY(mnY), maxX(mxX), maxY(mxY), tileID(id) {}
|
||||
|
||||
Type GetOutputType() const override { return Type::Int; }
|
||||
Type GetOutputType() const override { return Type::Float; }
|
||||
std::vector<Type> GetInputTypes() const override { return {}; }
|
||||
std::string GetName() const override { return "QueryRange"; }
|
||||
Value Evaluate(const EvalContext& ctx, const std::vector<Value>&) const override {
|
||||
@@ -304,7 +304,7 @@ public:
|
||||
for (int32_t dx = minX; dx <= maxX; ++dx)
|
||||
if (ctx.GetPrevTile(ctx.worldX + dx, ctx.worldY + dy) == tileID)
|
||||
++count;
|
||||
return Value::MakeInt(count);
|
||||
return Value::MakeFloat(static_cast<float>(count));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -381,6 +381,16 @@ public:
|
||||
Value Evaluate(const EvalContext& ctx, const std::vector<Value>&) const override { return Value::MakeFloat(ctx.worldY); };
|
||||
};
|
||||
|
||||
/// Outputs the current layer's blending strength, set by the world compositor.
|
||||
/// Returns 1.0 when running outside a layered world (normal graph evaluation).
|
||||
class LayerStrengthNode : public Node {
|
||||
public:
|
||||
Type GetOutputType() const override { return Type::Float; }
|
||||
std::vector<Type> GetInputTypes() const override { return {}; }
|
||||
std::string GetName() const override { return "LayerStrength"; }
|
||||
Value Evaluate(const EvalContext& ctx, const std::vector<Value>&) const override { return Value::MakeFloat(ctx.layerStrength); }
|
||||
};
|
||||
|
||||
// ─────────────────────────────── Abs / Negate ────────────────────────────────
|
||||
|
||||
/// |a| (Float)
|
||||
@@ -501,6 +511,30 @@ public:
|
||||
|
||||
// ─────────────────────────────── Extended math nodes ─────────────────────────
|
||||
|
||||
/// floor(a) (Float)
|
||||
class FloorNode : public Node {
|
||||
public:
|
||||
Type GetOutputType() const override { return Type::Float; }
|
||||
std::vector<Type> GetInputTypes() const override { return { Type::Float }; }
|
||||
std::string GetName() const override { return "Floor"; }
|
||||
Value Evaluate(const EvalContext&, const std::vector<Value>& in) const override {
|
||||
DEV_ASSERT(in.size() == 1);
|
||||
return Value::MakeFloat(std::floor(in[0].AsFloat()));
|
||||
}
|
||||
};
|
||||
|
||||
/// ceil(a) (Float)
|
||||
class CeilNode : public Node {
|
||||
public:
|
||||
Type GetOutputType() const override { return Type::Float; }
|
||||
std::vector<Type> GetInputTypes() const override { return { Type::Float }; }
|
||||
std::string GetName() const override { return "Ceil"; }
|
||||
Value Evaluate(const EvalContext&, const std::vector<Value>& in) const override {
|
||||
DEV_ASSERT(in.size() == 1);
|
||||
return Value::MakeFloat(std::ceil(in[0].AsFloat()));
|
||||
}
|
||||
};
|
||||
|
||||
/// sqrt(a), clamped to 0 for negative inputs (Float)
|
||||
class SqrtNode : public Node {
|
||||
public:
|
||||
@@ -605,6 +639,28 @@ public:
|
||||
// Each noise node reads worldX/Y and seed from EvalContext; no graph inputs.
|
||||
// Output is a Float in [-1, 1].
|
||||
//
|
||||
// RandomNode is the exception: it produces spatially incoherent white noise
|
||||
// via a hash of (seed, worldX, worldY), output in [0, 1].
|
||||
|
||||
/// Spatially incoherent hash-based random value in [0, 1].
|
||||
/// Each (seed, worldX, worldY) triple produces an independent value — no
|
||||
/// smoothing, no spatial correlation. (Float)
|
||||
class RandomNode : public Node {
|
||||
public:
|
||||
Type GetOutputType() const override { return Type::Float; }
|
||||
std::vector<Type> GetInputTypes() const override { return {}; }
|
||||
std::string GetName() const override { return "Random"; }
|
||||
Value Evaluate(const EvalContext& ctx, const std::vector<Value>&) const override {
|
||||
// Mix seed, x, y with Knuth multiplicative hashes then finalise.
|
||||
uint32_t h = static_cast<uint32_t>(ctx.seed)
|
||||
^ (static_cast<uint32_t>(ctx.worldX) * 2654435761u)
|
||||
^ (static_cast<uint32_t>(ctx.worldY) * 2246822519u);
|
||||
h ^= h >> 16;
|
||||
h *= 0x45d9f3bu;
|
||||
h ^= h >> 16;
|
||||
return Value::MakeFloat((h & 0xFFFFFFu) / static_cast<float>(0x1000000u));
|
||||
}
|
||||
};
|
||||
// A new FastNoiseLite object is constructed per evaluation so that the seed
|
||||
// from the context is applied correctly across every cell.
|
||||
|
||||
|
||||
@@ -44,6 +44,11 @@ struct EvalContext {
|
||||
int32_t prevWidth { 0 };
|
||||
int32_t prevHeight { 0 };
|
||||
|
||||
// ── Layer blending strength ────────────────────────────────────────────
|
||||
// Set by the world layer compositor before calling Evaluate().
|
||||
// 1.0 = this layer is fully active; 0.0 = this layer has no influence.
|
||||
float layerStrength { 1.0f };
|
||||
|
||||
/// Query the previous pass at an absolute world position.
|
||||
/// Returns 0 (AIR / empty) when no previous pass or position is out of bounds.
|
||||
inline int32_t GetPrevTile(int32_t x, int32_t y) const noexcept;
|
||||
|
||||
Reference in New Issue
Block a user