mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-23 09:04:21 +00:00
Library/Math: Implement FractalGenerator (#971)
This commit is contained in:
parent
b8858e4037
commit
004cb2ef50
|
|
@ -260640,11 +260640,11 @@ Library/Math/MathUtil.o:
|
|||
- offset: 0x9312b8
|
||||
size: 100
|
||||
label: _ZN2al11calcFractalEffjfffb
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x93131c
|
||||
size: 116
|
||||
label: _ZN2al16calcMultiFractalEfffjfffb
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x931390
|
||||
size: 112
|
||||
label: _ZN2al22calcNormalDistributionEfff
|
||||
|
|
@ -294004,35 +294004,35 @@ Project/Math/FractalGenerator.o:
|
|||
label:
|
||||
- _ZN2al16FractalGeneratorC1Ejfff
|
||||
- _ZN2al16FractalGeneratorC2Ejfff
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa6a884
|
||||
size: 20
|
||||
label: _ZN2al16FractalGenerator8setParamEjfff
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa6a898
|
||||
size: 220
|
||||
label: _ZN2al16FractalGenerator11calcFractalEffb
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa6a974
|
||||
size: 228
|
||||
label: _ZN2al16FractalGenerator21makeSmoothPerlinNoiseEff
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa6aa58
|
||||
size: 340
|
||||
label: _ZN2al16FractalGenerator15makePerlinNoiseEff
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa6abac
|
||||
size: 232
|
||||
label: _ZN2al16FractalGenerator16calcMultiFractalEfffb
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa6ac94
|
||||
size: 84
|
||||
label: _ZN2al16FractalGenerator10makeRandomEii
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0xa6ace8
|
||||
size: 452
|
||||
label: _ZN2al16FractalGenerator16makeSmoothRandomEii
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
Project/Memory/MemorySystem.o:
|
||||
'.text':
|
||||
- offset: 0xa6aeac
|
||||
|
|
|
|||
122
lib/al/Library/Math/FractalGenerator.cpp
Normal file
122
lib/al/Library/Math/FractalGenerator.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#include "Library/Math/FractalGenerator.h"
|
||||
|
||||
#include "Library/Math/MathUtil.h"
|
||||
|
||||
namespace al {
|
||||
FractalGenerator::FractalGenerator(u32 permutations, f32 amplitude, f32 scale,
|
||||
f32 nextOrderAmplitude)
|
||||
: mPermutations(permutations), mAmplitude(amplitude), mScale(scale),
|
||||
mNextOrderAmplitude(nextOrderAmplitude) {}
|
||||
|
||||
void FractalGenerator::setParam(u32 permutations, f32 amplitude, f32 scale,
|
||||
f32 nextOrderAmplitude) {
|
||||
mPermutations = permutations;
|
||||
mAmplitude = amplitude;
|
||||
mScale = scale;
|
||||
mNextOrderAmplitude = nextOrderAmplitude;
|
||||
}
|
||||
|
||||
f32 FractalGenerator::calcFractal(f32 x, f32 y, bool useSmoothPerlingNoise) {
|
||||
f32 value = 0.0f;
|
||||
|
||||
f32 amplitude = mAmplitude;
|
||||
f32 scale = mScale;
|
||||
for (s32 i = 0; i < (s32)(mPermutations - 1); i++) {
|
||||
if (useSmoothPerlingNoise)
|
||||
value += makeSmoothPerlinNoise(scale * x, scale * y) * amplitude;
|
||||
else
|
||||
value += makePerlinNoise(scale * x, scale * y) * amplitude;
|
||||
|
||||
scale *= 2;
|
||||
amplitude *= mNextOrderAmplitude;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
f32 FractalGenerator::makeSmoothPerlinNoise(f32 x, f32 y) {
|
||||
s32 gridX = (s32)x;
|
||||
s32 gridY = (s32)y;
|
||||
f32 fracX = x - gridX;
|
||||
f32 fracY = y - gridY;
|
||||
|
||||
// NOTE: ASM is using an undef call for subsequent calls. This is not a bug since
|
||||
// makeSmoothRandom doesn't make use of any class members. This is probably a compiler
|
||||
// optimization error
|
||||
FractalGenerator* gen;
|
||||
f32 r00 = makeSmoothRandom(gridX, gridY);
|
||||
f32 r10 = gen->makeSmoothRandom(gridX + 1, gridY);
|
||||
f32 r01 = gen->makeSmoothRandom(gridX, gridY + 1);
|
||||
f32 r11 = gen->makeSmoothRandom(gridX + 1, gridY + 1);
|
||||
|
||||
return lerpValue(lerpValue(r00, r10, easeInOut(fracX)), lerpValue(r01, r11, easeInOut(fracX)),
|
||||
easeInOut(fracY));
|
||||
}
|
||||
|
||||
f32 FractalGenerator::makePerlinNoise(f32 x, f32 y) {
|
||||
s32 gridX = (s32)x;
|
||||
s32 gridY = (s32)y;
|
||||
f32 fracX = x - gridX;
|
||||
f32 fracY = y - gridY;
|
||||
|
||||
f32 r00 = makeRandom(gridX, gridY);
|
||||
f32 r10 = makeRandom(gridX + 1, gridY);
|
||||
f32 r01 = makeRandom(gridX, gridY + 1);
|
||||
f32 r11 = makeRandom(gridX + 1, gridY + 1);
|
||||
|
||||
return lerpValue(lerpValue(r00, r10, easeInOut(fracX)), lerpValue(r01, r11, easeInOut(fracX)),
|
||||
easeInOut(fracY));
|
||||
}
|
||||
|
||||
f32 FractalGenerator::calcMultiFractal(f32 x, f32 y, f32 baseAmplitude,
|
||||
bool useSmoothPerlingNoise) {
|
||||
f32 value = 1.0f;
|
||||
|
||||
f32 amplitude = mAmplitude;
|
||||
f32 scale = mScale;
|
||||
for (s32 i = 0; i < (s32)(mPermutations - 1); i++) {
|
||||
if (useSmoothPerlingNoise)
|
||||
value *= baseAmplitude * makeSmoothPerlinNoise(scale * x, scale * y) * amplitude;
|
||||
else
|
||||
value *= baseAmplitude * makePerlinNoise(scale * x, scale * y) * amplitude;
|
||||
|
||||
scale *= 2;
|
||||
amplitude *= mNextOrderAmplitude;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline s32 makeSeed(s32 x, s32 y) {
|
||||
s32 seed = x + y * 57;
|
||||
seed ^= seed << 13;
|
||||
return seed;
|
||||
}
|
||||
|
||||
inline f32 makeNoise(s32 seed) {
|
||||
// NOTE: The only true random are all these magic values
|
||||
s32 hash = (seed * seed * 0x4bd9 + 0x2e59b) * seed + 0x4bcb4b;
|
||||
return static_cast<f32>(hash & 0x4b746f) / -3354521.0f;
|
||||
}
|
||||
|
||||
f32 FractalGenerator::makeRandom(s32 x, s32 y) {
|
||||
return makeNoise(makeSeed(x, y)) + 1.0f;
|
||||
}
|
||||
|
||||
f32 FractalGenerator::makeSmoothRandom(s32 x, s32 y) {
|
||||
constexpr f32 weight_corners = 0.25f;
|
||||
constexpr f32 weight_sides = 0.5f;
|
||||
constexpr f32 weight_center = 0.25f;
|
||||
|
||||
f32 corners = (makeRandom(x - 1, y - 1) + makeRandom(x + 1, y - 1) + makeRandom(x - 1, y + 1) +
|
||||
makeRandom(x + 1, y + 1)) *
|
||||
((1.0f / 4.0f) * weight_corners);
|
||||
f32 sides = (makeRandom(x - 1, y) + makeRandom(x + 1, y) + makeRandom(x, y - 1) +
|
||||
makeRandom(x, y + 1)) *
|
||||
((1.0f / 4.0f) * weight_sides);
|
||||
;
|
||||
f32 center = makeRandom(x, y) * weight_center;
|
||||
return corners + sides + center;
|
||||
}
|
||||
|
||||
} // namespace al
|
||||
26
lib/al/Library/Math/FractalGenerator.h
Normal file
26
lib/al/Library/Math/FractalGenerator.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include <basis/seadTypes.h>
|
||||
|
||||
namespace al {
|
||||
|
||||
class FractalGenerator {
|
||||
public:
|
||||
FractalGenerator(u32 permutations, f32 amplitude, f32 scale, f32 nextOrderAmplitude);
|
||||
|
||||
void setParam(u32 permutations, f32 amplitude, f32 scale, f32 nextOrderAmplitude);
|
||||
f32 calcFractal(f32 x, f32 y, bool useSmoothPerlingNoise);
|
||||
f32 makeSmoothPerlinNoise(f32 x, f32 y);
|
||||
f32 makePerlinNoise(f32 x, f32 y);
|
||||
f32 calcMultiFractal(f32 x, f32 y, f32 baseAmplitude, bool useSmoothPerlingNoise);
|
||||
f32 makeRandom(s32 x, s32 y);
|
||||
f32 makeSmoothRandom(s32 x, s32 y);
|
||||
|
||||
private:
|
||||
u32 mPermutations;
|
||||
f32 mAmplitude;
|
||||
f32 mScale;
|
||||
f32 mNextOrderAmplitude;
|
||||
};
|
||||
|
||||
} // namespace al
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
#include <random/seadGlobalRandom.h>
|
||||
|
||||
#include "Library/Base/HashCodeUtil.h"
|
||||
#include "Library/Math/FractalGenerator.h"
|
||||
#include "Library/Matrix/MatrixUtil.h"
|
||||
|
||||
namespace al {
|
||||
|
|
@ -1742,6 +1743,18 @@ f32 convertSpringEnergyToSpeed(f32 a, f32 b, f32 c) {
|
|||
return sead::Mathf::sqrt(a * c * a + b * b);
|
||||
}
|
||||
|
||||
f32 calcFractal(f32 x, f32 y, u32 permutations, f32 amplitude, f32 scale, f32 nextOrderAmplitude,
|
||||
bool useSmoothPerlingNoise) {
|
||||
FractalGenerator generator(permutations, amplitude, scale, nextOrderAmplitude);
|
||||
return generator.calcFractal(x, y, useSmoothPerlingNoise);
|
||||
}
|
||||
|
||||
f32 calcMultiFractal(f32 x, f32 y, f32 baseAmplitude, u32 permutations, f32 amplitude, f32 scale,
|
||||
f32 nextOrderAmplitude, bool useSmoothPerlingNoise) {
|
||||
FractalGenerator generator(permutations, amplitude, scale, nextOrderAmplitude);
|
||||
return generator.calcMultiFractal(x, y, baseAmplitude, useSmoothPerlingNoise);
|
||||
}
|
||||
|
||||
const char* axisIndexToString(s32 axisIndex) {
|
||||
switch (axisIndex) {
|
||||
case 0:
|
||||
|
|
|
|||
|
|
@ -494,8 +494,10 @@ void visitCellsOverlapped(const sead::Vector3f&, const sead::Vector3f&, f32,
|
|||
const VisitCellCallBack&);
|
||||
f32 calcMultValueToDestination(u32, f32, f32);
|
||||
f32 getHaltonSequence(u32, u32);
|
||||
f32 calcFractal(f32, f32, u32, f32, f32, f32, bool);
|
||||
f32 calcMultiFractal(f32, f32, f32, u32, f32, f32, f32, bool);
|
||||
f32 calcFractal(f32 x, f32 y, u32 permutations, f32 amplitude, f32 scale, f32 nextOrderAmplitude,
|
||||
bool useSmoothPerlingNoise);
|
||||
f32 calcMultiFractal(f32 x, f32 y, f32 baseAmplitude, u32 permutations, f32 amplitude, f32 scale,
|
||||
f32 nextOrderAmplitude, bool useSmoothPerlingNoise);
|
||||
f32 calcNormalDistribution(f32, f32, f32);
|
||||
bool calcVecViewInput(sead::Vector3f*, const sead::Vector2f&, const sead::Vector3f&,
|
||||
const sead::Matrix34f*);
|
||||
|
|
|
|||
Loading…
Reference in a new issue