kopia lustrzana https://github.com/jameshball/osci-render
Fix SVG parsing bugs, object parsing bugs, rotation precision errors
rodzic
2157b8a867
commit
398f3268f5
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <numbers>
|
||||
|
||||
class MathUtil {
|
||||
public:
|
||||
|
||||
// from https://stackoverflow.com/questions/11980292/how-to-wrap-around-a-range
|
||||
static inline double wrapAngle(double angle) {
|
||||
double twoPi = 2.0 * std::numbers::pi;
|
||||
return angle - twoPi * floor(angle / twoPi);
|
||||
}
|
||||
};
|
|
@ -1,16 +1,14 @@
|
|||
#include "EffectApplication.h"
|
||||
#include <numbers>
|
||||
#include "../MathUtil.h"
|
||||
|
||||
void EffectApplication::resetPhase() {
|
||||
phase = 0.0;
|
||||
}
|
||||
|
||||
double EffectApplication::nextPhase(double frequency, double sampleRate) {
|
||||
phase += frequency / sampleRate;
|
||||
phase += 2 * std::numbers::pi * frequency / sampleRate;
|
||||
phase = MathUtil::wrapAngle(phase);
|
||||
|
||||
if (phase > 1) {
|
||||
phase -= 1;
|
||||
}
|
||||
|
||||
return phase * 2 * std::numbers::pi;
|
||||
return phase;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "PerspectiveEffect.h"
|
||||
#include <numbers>
|
||||
#include "../MathUtil.h"
|
||||
|
||||
PerspectiveEffect::PerspectiveEffect(int versionHint) : versionHint(versionHint) {
|
||||
fixedRotateX = new BooleanParameter("Perspective Fixed Rotate X", "perspectiveFixedRotateX", versionHint, false);
|
||||
|
@ -31,19 +32,9 @@ Vector2 PerspectiveEffect::apply(int index, Vector2 input, const std::vector<dou
|
|||
baseRotateZ = values[5] * std::numbers::pi;
|
||||
}
|
||||
|
||||
currentRotateX += baseRotateX * rotateSpeed;
|
||||
currentRotateY += baseRotateY * rotateSpeed;
|
||||
currentRotateZ += baseRotateZ * rotateSpeed;
|
||||
|
||||
if (currentRotateX > std::numbers::pi * 8) {
|
||||
currentRotateX -= std::numbers::pi * 8;
|
||||
}
|
||||
if (currentRotateY > std::numbers::pi * 8) {
|
||||
currentRotateY -= std::numbers::pi * 8;
|
||||
}
|
||||
if (currentRotateZ > std::numbers::pi * 8) {
|
||||
currentRotateZ -= std::numbers::pi * 8;
|
||||
}
|
||||
currentRotateX = MathUtil::wrapAngle(currentRotateX + baseRotateX * rotateSpeed);
|
||||
currentRotateY = MathUtil::wrapAngle(currentRotateY + baseRotateY * rotateSpeed);
|
||||
currentRotateZ = MathUtil::wrapAngle(currentRotateZ + baseRotateZ * rotateSpeed);
|
||||
|
||||
auto x = input.x;
|
||||
auto y = input.y;
|
||||
|
|
|
@ -28,7 +28,11 @@ private:
|
|||
|
||||
int versionHint;
|
||||
|
||||
float linearSpeedToActualSpeed(float rotateSpeed) {
|
||||
return (std::exp(3 * juce::jmin(10.0f, std::abs(rotateSpeed))) - 1) / 50000.0;
|
||||
}
|
||||
double linearSpeedToActualSpeed(double rotateSpeed) {
|
||||
double actualSpeed = (std::exp(3 * std::min(10.0, std::abs(rotateSpeed))) - 1) / 50000;
|
||||
if (rotateSpeed < 0) {
|
||||
actualSpeed *= -1;
|
||||
}
|
||||
return actualSpeed;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,8 +12,10 @@ Graph::Graph(int n, list< pair<int, int> > & edges):
|
|||
{
|
||||
int u = (*it).first;
|
||||
int v = (*it).second;
|
||||
|
||||
AddEdge(u, v);
|
||||
|
||||
if (v < n && u < n) {
|
||||
AddEdge(u, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "WorldObject.h"
|
||||
#include "../chinese_postman/ChinesePostman.h"
|
||||
#include "tiny_obj_loader.h"
|
||||
#include "../MathUtil.h"
|
||||
|
||||
struct pair_hash {
|
||||
inline std::size_t operator()(const std::pair<int, int>& v) const {
|
||||
|
@ -238,9 +239,9 @@ void WorldObject::setRotationSpeed(double rotateSpeed) {
|
|||
// called whenever a new frame is drawn, so that the object can update its
|
||||
// rotation
|
||||
void WorldObject::nextFrame() {
|
||||
currentRotateX = currentRotateX + baseRotateX * rotateSpeed;
|
||||
currentRotateY = currentRotateY + baseRotateY * rotateSpeed;
|
||||
currentRotateZ = currentRotateZ + baseRotateZ * rotateSpeed;
|
||||
currentRotateX = MathUtil::wrapAngle(currentRotateX + baseRotateX * rotateSpeed);
|
||||
currentRotateY = MathUtil::wrapAngle(currentRotateY + baseRotateY * rotateSpeed);
|
||||
currentRotateZ = MathUtil::wrapAngle(currentRotateZ + baseRotateZ * rotateSpeed);
|
||||
rotateX = baseRotateX + currentRotateX;
|
||||
rotateY = baseRotateY + currentRotateY;
|
||||
rotateZ = baseRotateZ + currentRotateZ;
|
||||
|
|
|
@ -45,7 +45,7 @@ double Vector2::magnitude() {
|
|||
}
|
||||
|
||||
std::unique_ptr<Shape> Vector2::clone() {
|
||||
return std::unique_ptr<Shape>();
|
||||
return std::make_unique<Vector2>(x, y);
|
||||
}
|
||||
|
||||
std::string Vector2::type() {
|
||||
|
|
|
@ -5,17 +5,26 @@
|
|||
|
||||
SvgParser::SvgParser(juce::String svgFile) {
|
||||
auto doc = juce::XmlDocument::parse(svgFile);
|
||||
std::unique_ptr<juce::Drawable> svg = juce::Drawable::createFromSVG(*doc);
|
||||
juce::DrawableComposite* composite = dynamic_cast<juce::DrawableComposite*>(svg.get());
|
||||
auto contentArea = composite->getContentArea();
|
||||
auto path = svg->getOutlineAsPath();
|
||||
// apply transform to path to get the content area in the bounds -1 to 1
|
||||
path.applyTransform(juce::AffineTransform::translation(-contentArea.getX(), -contentArea.getY()));
|
||||
path.applyTransform(juce::AffineTransform::scale(2 / contentArea.getWidth(), 2 / contentArea.getHeight()));
|
||||
path.applyTransform(juce::AffineTransform::translation(-1, -1));
|
||||
if (doc != nullptr) {
|
||||
std::unique_ptr<juce::Drawable> svg = juce::Drawable::createFromSVG(*doc);
|
||||
juce::DrawableComposite* composite = dynamic_cast<juce::DrawableComposite*>(svg.get());
|
||||
if (composite != nullptr) {
|
||||
auto contentArea = composite->getContentArea();
|
||||
auto path = svg->getOutlineAsPath();
|
||||
// apply transform to path to get the content area in the bounds -1 to 1
|
||||
path.applyTransform(juce::AffineTransform::translation(-contentArea.getX(), -contentArea.getY()));
|
||||
path.applyTransform(juce::AffineTransform::scale(2 / contentArea.getWidth(), 2 / contentArea.getHeight()));
|
||||
path.applyTransform(juce::AffineTransform::translation(-1, -1));
|
||||
|
||||
pathToShapes(path, shapes);
|
||||
Shape::removeOutOfBounds(shapes);
|
||||
pathToShapes(path, shapes);
|
||||
Shape::removeOutOfBounds(shapes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// draw an X to indicate an error.
|
||||
shapes.push_back(std::make_unique<Line>(-0.5, -0.5, 0.5, 0.5));
|
||||
shapes.push_back(std::make_unique<Line>(-0.5, 0.5, 0.5, -0.5));
|
||||
}
|
||||
|
||||
SvgParser::~SvgParser() {}
|
||||
|
@ -69,4 +78,4 @@ std::vector<std::unique_ptr<Shape>> SvgParser::draw() {
|
|||
tempShapes.push_back(shape->clone());
|
||||
}
|
||||
return tempShapes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -380,6 +380,7 @@
|
|||
<FILE id="GKBQ8j" name="MainComponent.cpp" compile="1" resource="0"
|
||||
file="Source/MainComponent.cpp"/>
|
||||
<FILE id="RU8fGr" name="MainComponent.h" compile="0" resource="0" file="Source/MainComponent.h"/>
|
||||
<FILE id="cFVaxu" name="MathUtil.h" compile="0" resource="0" file="Source/MathUtil.h"/>
|
||||
<FILE id="eB92KJ" name="MidiComponent.cpp" compile="1" resource="0"
|
||||
file="Source/MidiComponent.cpp"/>
|
||||
<FILE id="GJqoJa" name="MidiComponent.h" compile="0" resource="0" file="Source/MidiComponent.h"/>
|
||||
|
|
Ładowanie…
Reference in New Issue