kopia lustrzana https://github.com/jameshball/osci-render
Allow x, y, and z values to be transformed using the 3D depth effect
rodzic
6553e6391c
commit
9194209a66
|
@ -1,17 +1,27 @@
|
|||
package sh.ball.audio.effect;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import sh.ball.engine.Vector3;
|
||||
import sh.ball.parser.lua.LuaExecutor;
|
||||
import sh.ball.shapes.Vector2;
|
||||
|
||||
import javax.xml.transform.Result;
|
||||
|
||||
// 3D rotation effect
|
||||
public class PerspectiveEffect implements SettableEffect {
|
||||
|
||||
private final LuaExecutor executor;
|
||||
|
||||
private double zPos = 1.0;
|
||||
private Vector3 baseRotation = new Vector3(Math.PI, Math.PI, 0);
|
||||
private Vector3 currentRotation = new Vector3();
|
||||
private double rotateSpeed = 0.0;
|
||||
private double effectScale = 1.0;
|
||||
|
||||
public PerspectiveEffect(LuaExecutor executor) {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2 apply(int count, Vector2 vector) {
|
||||
currentRotation = currentRotation.add(baseRotation.scale(rotateSpeed));
|
||||
|
@ -19,10 +29,23 @@ public class PerspectiveEffect implements SettableEffect {
|
|||
Vector3 vertex = new Vector3(vector.x, vector.y, 0.0);
|
||||
vertex = vertex.rotate(baseRotation.add(currentRotation));
|
||||
|
||||
executor.setVariable("x", vertex.x);
|
||||
executor.setVariable("y", vertex.y);
|
||||
executor.setVariable("z", -zPos);
|
||||
double x = vertex.x;
|
||||
double y = vertex.y;
|
||||
double z = -zPos;
|
||||
try {
|
||||
LuaValue result = executor.execute();
|
||||
x = result.get(1).checkdouble();
|
||||
y = result.get(2).checkdouble();
|
||||
z = result.get(3).checkdouble();
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
double focalLength = 1.0;
|
||||
return new Vector2(
|
||||
(1 - effectScale) * vector.x + effectScale * (vertex.x * focalLength / (vertex.z - zPos)),
|
||||
(1 - effectScale) * vector.y + effectScale * (vertex.y * focalLength / (vertex.z - zPos))
|
||||
(1 - effectScale) * vector.x + effectScale * (x * focalLength / z),
|
||||
(1 - effectScale) * vector.y + effectScale * (y * focalLength / z)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package sh.ball.audio.engine;
|
||||
|
||||
import com.sun.javafx.PlatformUtil;
|
||||
import sh.ball.shapes.Vector2;
|
||||
import xt.audio.*;
|
||||
|
||||
|
@ -237,13 +236,7 @@ public class XtAudioEngine implements AudioEngine {
|
|||
|
||||
// connects to an XtAudio XtService in order of lowest latency to highest latency
|
||||
private XtService getService(XtPlatform platform) {
|
||||
XtService service = null;
|
||||
if ((PlatformUtil.isLinux() || PlatformUtil.isUnix()) && !PlatformUtil.isMac()) {
|
||||
service = platform.getService(Enums.XtSystem.JACK);
|
||||
}
|
||||
if (service == null) {
|
||||
service = platform.getService(platform.setupToSystem(Enums.XtSetup.SYSTEM_AUDIO));
|
||||
}
|
||||
XtService service = platform.getService(platform.setupToSystem(Enums.XtSetup.SYSTEM_AUDIO));
|
||||
if (service == null) {
|
||||
service = platform.getService(platform.setupToSystem(Enums.XtSetup.PRO_AUDIO));
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.nio.file.Path;
|
|||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.logging.*;
|
||||
|
||||
public class Gui extends Application {
|
||||
|
@ -40,12 +41,11 @@ public class Gui extends Application {
|
|||
public static String LOG_DIR = "./logs/";
|
||||
public static final Logger logger = Logger.getLogger(Gui.class.getName());
|
||||
|
||||
public static ProjectSelectController projectSelectController;
|
||||
public static ShapeAudioPlayer audioPlayer;
|
||||
public static AudioDevice defaultDevice;
|
||||
public static CodeEditor editor;
|
||||
public static Stage editorStage;
|
||||
public static Scene editorScene;
|
||||
|
||||
private static CodeEditor editor;
|
||||
private static Stage editorStage;
|
||||
|
||||
static {
|
||||
try {
|
||||
|
@ -79,13 +79,11 @@ public class Gui extends Application {
|
|||
new Thread(midiCommunicator).start();
|
||||
}
|
||||
|
||||
private Stage stage;
|
||||
private Scene scene;
|
||||
private Parent root;
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws Exception {
|
||||
this.stage = stage;
|
||||
System.setProperty("prism.lcdtext", "false");
|
||||
System.setProperty("org.luaj.luajc", "true");
|
||||
|
||||
|
@ -93,7 +91,7 @@ public class Gui extends Application {
|
|||
|
||||
FXMLLoader projectSelectLoader = new FXMLLoader(getClass().getResource("/fxml/projectSelect.fxml"));
|
||||
Parent projectSelectRoot = projectSelectLoader.load();
|
||||
projectSelectController = projectSelectLoader.getController();
|
||||
ProjectSelectController projectSelectController = projectSelectLoader.getController();
|
||||
projectSelectController.setOpenBrowser(url -> getHostServices().showDocument(url));
|
||||
|
||||
stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResourceAsStream("/icons/icon.png"))));
|
||||
|
@ -166,12 +164,11 @@ public class Gui extends Application {
|
|||
editor = new CodeEditor();
|
||||
editor.initialize();
|
||||
editorStage = new Stage();
|
||||
editorScene = new Scene(editor, 900, 600, false, SceneAntialiasing.BALANCED);
|
||||
Scene editorScene = new Scene(editor, 900, 600, false, SceneAntialiasing.BALANCED);
|
||||
editorStage.setScene(editorScene);
|
||||
editorStage.getIcons().add(new Image(Objects.requireNonNull(Gui.class.getResourceAsStream("/icons/icon.png"))));
|
||||
editor.prefHeightProperty().bind(editorStage.heightProperty());
|
||||
editor.prefWidthProperty().bind(editorStage.widthProperty());
|
||||
editor.setCallback(controller::updateFileData);
|
||||
}
|
||||
|
||||
public void launchMainApplication(MainController controller, String projectPath, Boolean muted) throws Exception {
|
||||
|
@ -194,20 +191,12 @@ public class Gui extends Application {
|
|||
}
|
||||
}
|
||||
|
||||
public static void launchCodeEditor(String code, String fileName) {
|
||||
public static void launchCodeEditor(String code, String fileName, String mimeType, BiConsumer<byte[], String> callback) {
|
||||
editor.setCode(code, fileName);
|
||||
editor.setCallback(callback);
|
||||
editorStage.show();
|
||||
editorStage.setTitle(fileName);
|
||||
|
||||
if (LuaParser.isLuaFile(fileName)) {
|
||||
editor.setMode("text/x-lua");
|
||||
} else if (ObjParser.isObjFile(fileName)) {
|
||||
editor.setMode("");
|
||||
} else if (SvgParser.isSvgFile(fileName)) {
|
||||
editor.setMode("text/html");
|
||||
} else if (TextParser.isTxtFile(fileName)) {
|
||||
editor.setMode("");
|
||||
}
|
||||
editor.setMode(mimeType);
|
||||
}
|
||||
|
||||
public static void closeCodeEditor() {
|
||||
|
|
|
@ -13,11 +13,15 @@ import org.w3c.dom.Element;
|
|||
import sh.ball.audio.FrequencyAnalyser;
|
||||
import sh.ball.audio.effect.*;
|
||||
import sh.ball.audio.engine.AudioDevice;
|
||||
import sh.ball.gui.Gui;
|
||||
import sh.ball.gui.components.EffectComponentGroup;
|
||||
import sh.ball.parser.lua.LuaExecutor;
|
||||
import sh.ball.parser.lua.LuaParser;
|
||||
import sh.ball.shapes.Shape;
|
||||
import sh.ball.shapes.Vector2;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -29,6 +33,8 @@ public class EffectsController implements Initializable, SubController {
|
|||
|
||||
private static final int DEFAULT_SAMPLE_RATE = 192000;
|
||||
|
||||
private final LuaExecutor executor = new LuaExecutor(LuaExecutor.STANDARD_GLOBALS);
|
||||
|
||||
private final WobbleEffect wobbleEffect;
|
||||
private final PerspectiveEffect perspectiveEffect;
|
||||
private final TranslateEffect translateEffect;
|
||||
|
@ -88,10 +94,12 @@ public class EffectsController implements Initializable, SubController {
|
|||
private Button resetRotationButton;
|
||||
@FXML
|
||||
private Button resetPerspectiveRotationButton;
|
||||
@FXML
|
||||
private Button depthFunctionButton;
|
||||
|
||||
public EffectsController() {
|
||||
this.wobbleEffect = new WobbleEffect(DEFAULT_SAMPLE_RATE);
|
||||
this.perspectiveEffect = new PerspectiveEffect();
|
||||
this.perspectiveEffect = new PerspectiveEffect(executor);
|
||||
this.translateEffect = new TranslateEffect(DEFAULT_SAMPLE_RATE, 1, new Vector2());
|
||||
this.rotateEffect = new RotateEffect(DEFAULT_SAMPLE_RATE);
|
||||
}
|
||||
|
@ -237,6 +245,14 @@ public class EffectsController implements Initializable, SubController {
|
|||
rotateSpeed3D.controller.slider.setValue(0);
|
||||
perspectiveEffect.resetRotation();
|
||||
});
|
||||
|
||||
String script = "return { x, y, z }";
|
||||
executor.setScript(script);
|
||||
depthFunctionButton.setOnAction(e -> Gui.launchCodeEditor(script, "3D Perspective Effect Depth Function", "text/x-lua", this::updateDepthFunction));
|
||||
}
|
||||
|
||||
private void updateDepthFunction(byte[] fileData, String fileName) {
|
||||
executor.setScript(new String(fileData, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
private List<EffectComponentGroup> effects() {
|
||||
|
|
|
@ -4,10 +4,15 @@ import javafx.animation.KeyFrame;
|
|||
import javafx.animation.Timeline;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.event.Event;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.skin.ComboBoxListViewSkin;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.SVGPath;
|
||||
|
@ -61,6 +66,7 @@ import sh.ball.parser.lua.LuaParser;
|
|||
import sh.ball.parser.obj.ObjFrameSettings;
|
||||
import sh.ball.parser.obj.ObjParser;
|
||||
import sh.ball.parser.ParserFactory;
|
||||
import sh.ball.parser.svg.SvgParser;
|
||||
import sh.ball.parser.txt.FontStyle;
|
||||
import sh.ball.shapes.Shape;
|
||||
import sh.ball.shapes.ShapeFrameSource;
|
||||
|
@ -142,6 +148,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
@FXML
|
||||
private MenuItem openProjectMenuItem;
|
||||
@FXML
|
||||
private Menu audioMenu;
|
||||
@FXML
|
||||
private Menu recentProjectMenu;
|
||||
@FXML
|
||||
private MenuItem saveProjectMenuItem;
|
||||
|
@ -184,6 +192,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
@FXML
|
||||
private ComboBox<AudioDevice> deviceComboBox;
|
||||
@FXML
|
||||
private CustomMenuItem audioDeviceMenuItem;
|
||||
@FXML
|
||||
private Slider brightnessSlider;
|
||||
@FXML
|
||||
private CustomMenuItem recordLengthMenuItem;
|
||||
|
@ -1397,7 +1407,14 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
void openCodeEditor() {
|
||||
String code = new String(openFiles.get(currentFrameSource), StandardCharsets.UTF_8);
|
||||
closeCodeEditor();
|
||||
launchCodeEditor(code, frameSourcePaths.get(currentFrameSource));
|
||||
String name = frameSourcePaths.get(currentFrameSource);
|
||||
String mimeType = "";
|
||||
if (LuaParser.isLuaFile(name)) {
|
||||
mimeType = "text/x-lua";
|
||||
} else if (SvgParser.isSvgFile(name)) {
|
||||
mimeType = "text/html";
|
||||
}
|
||||
launchCodeEditor(code, frameSourcePaths.get(currentFrameSource), mimeType, this::updateFileData);
|
||||
}
|
||||
|
||||
private void updateTitle(String message, String projectName) {
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
package sh.ball.parser.lua;
|
||||
|
||||
import org.luaj.vm2.*;
|
||||
import org.luaj.vm2.lib.ThreeArgFunction;
|
||||
import org.luaj.vm2.lib.TwoArgFunction;
|
||||
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.io.StringReader;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static sh.ball.gui.Gui.logger;
|
||||
|
||||
public class LuaExecutor {
|
||||
|
||||
public static final Globals STANDARD_GLOBALS = JsePlatform.standardGlobals();
|
||||
|
||||
static {
|
||||
org.luaj.vm2.luajc.LuaJC.install(STANDARD_GLOBALS);
|
||||
}
|
||||
|
||||
private final Globals globals;
|
||||
private final Map<LuaString, LuaValue> bindings = new HashMap<>();
|
||||
private final Set<LuaString> programDefinedVariables = new HashSet<>();
|
||||
private LuaFunction lastWorkingFunction;
|
||||
private String lastWorkingTextScript;
|
||||
private LuaFunction function;
|
||||
private String textScript;
|
||||
private long step = 1;
|
||||
|
||||
public LuaExecutor(Globals globals) {
|
||||
this.globals = globals;
|
||||
}
|
||||
|
||||
public void setScript(String script) {
|
||||
LuaFunction f = LuaExecutor.STANDARD_GLOBALS.load(new StringReader(script), "script").checkfunction();
|
||||
setFunction(script, f);
|
||||
}
|
||||
|
||||
private void setFunction(String textScript, LuaFunction function) {
|
||||
if (lastWorkingFunction == null) {
|
||||
lastWorkingFunction = function;
|
||||
lastWorkingTextScript = textScript;
|
||||
}
|
||||
this.function = function;
|
||||
this.textScript = textScript;
|
||||
}
|
||||
|
||||
public LuaValue execute() {
|
||||
try {
|
||||
boolean updatedFile = false;
|
||||
|
||||
globals.setmetatable(new BindingsMetatable(bindings));
|
||||
bindings.put(LuaValue.valueOf("step"), LuaValue.valueOf((double) step));
|
||||
|
||||
LuaValue result;
|
||||
try {
|
||||
result = (LuaValue) LuaExecutor.eval(function, globals);
|
||||
if (!lastWorkingTextScript.equals(textScript)) {
|
||||
lastWorkingFunction = function;
|
||||
lastWorkingTextScript = textScript;
|
||||
updatedFile = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.INFO, e.getMessage(), e);
|
||||
result = (LuaValue) LuaExecutor.eval(lastWorkingFunction, globals);
|
||||
}
|
||||
step++;
|
||||
|
||||
if (updatedFile) {
|
||||
// reset variables
|
||||
step = 1;
|
||||
List<LuaString> variablesToRemove = new ArrayList<>();
|
||||
bindings.keySet().forEach(name -> {
|
||||
if (!programDefinedVariables.contains(name)) {
|
||||
variablesToRemove.add(name);
|
||||
}
|
||||
});
|
||||
variablesToRemove.forEach(bindings::remove);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.INFO, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return LuaValue.NIL;
|
||||
}
|
||||
|
||||
public void setVariable(String variableName, Object value) {
|
||||
LuaString name = LuaValue.valueOf(variableName);
|
||||
programDefinedVariables.add(name);
|
||||
bindings.put(name, toLua(value));
|
||||
}
|
||||
|
||||
public void resetStep() {
|
||||
step = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2007 LuaJ. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit p ersons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
------------------------------
|
||||
|
||||
The below functions have all been modified by James Ball to optimise Lua parsing
|
||||
on machines with poorer performance.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
static class BindingsMetatable extends LuaTable {
|
||||
|
||||
BindingsMetatable(Map<LuaString, LuaValue> bindings) {
|
||||
this.rawset(LuaValue.INDEX, new TwoArgFunction() {
|
||||
public LuaValue call(LuaValue table, LuaValue key) {
|
||||
LuaValue value = bindings.get(key.checkstring());
|
||||
if (value == null) {
|
||||
return LuaValue.NIL;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.rawset(LuaValue.NEWINDEX, new ThreeArgFunction() {
|
||||
public LuaValue call(LuaValue table, LuaValue key, LuaValue value) {
|
||||
if (value == null || value.type() == LuaValue.TNIL) {
|
||||
bindings.remove(key.checkstring());
|
||||
} else {
|
||||
bindings.put(key.checkstring(), value);
|
||||
}
|
||||
return LuaValue.NONE;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static private LuaValue toLua(Object javaValue) {
|
||||
return javaValue == null? LuaValue.NIL:
|
||||
javaValue instanceof LuaValue? (LuaValue) javaValue:
|
||||
CoerceJavaToLua.coerce(javaValue);
|
||||
}
|
||||
|
||||
static private Object toJava(LuaValue luajValue) {
|
||||
return switch (luajValue.type()) {
|
||||
case LuaValue.TNIL -> null;
|
||||
case LuaValue.TSTRING -> luajValue.tojstring();
|
||||
case LuaValue.TUSERDATA -> luajValue.checkuserdata(Object.class);
|
||||
case LuaValue.TNUMBER -> luajValue.isinttype() ?
|
||||
(Object) luajValue.toint() :
|
||||
(Object) luajValue.todouble();
|
||||
default -> luajValue;
|
||||
};
|
||||
}
|
||||
|
||||
static private Object toJava(Varargs v) {
|
||||
final int n = v.narg();
|
||||
switch (n) {
|
||||
case 0: return null;
|
||||
case 1: return toJava(v.arg1());
|
||||
default:
|
||||
Object[] o = new Object[n];
|
||||
for (int i=0; i<n; ++i)
|
||||
o[i] = toJava(v.arg(i+1));
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
static private Object eval(LuaFunction f, Globals g) throws ScriptException {
|
||||
try {
|
||||
f = f.getClass().newInstance();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
throw new ScriptException(e);
|
||||
}
|
||||
f.initupvalue1(g);
|
||||
return toJava(f.invoke(LuaValue.NONE));
|
||||
}
|
||||
}
|
|
@ -1,25 +1,15 @@
|
|||
package sh.ball.parser.lua;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
import sh.ball.audio.FrameSource;
|
||||
import sh.ball.parser.FileParser;
|
||||
import sh.ball.shapes.Vector2;
|
||||
|
||||
import javax.script.*;
|
||||
import java.io.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class LuaParser extends FileParser<FrameSource<Vector2>> {
|
||||
|
||||
private static final Globals globals = JsePlatform.standardGlobals();
|
||||
|
||||
static {
|
||||
org.luaj.vm2.luajc.LuaJC.install(globals);
|
||||
}
|
||||
|
||||
private final LuaSampleSource sampleSource = new LuaSampleSource(globals);
|
||||
private final LuaSampleSource sampleSource = new LuaSampleSource(LuaExecutor.STANDARD_GLOBALS);
|
||||
|
||||
private String script;
|
||||
|
||||
|
@ -35,10 +25,7 @@ public class LuaParser extends FileParser<FrameSource<Vector2>> {
|
|||
|
||||
@Override
|
||||
public FrameSource<Vector2> parse() throws Exception {
|
||||
LuaFunction f = globals.load(new StringReader(script), "script").checkfunction();
|
||||
|
||||
sampleSource.setFunction(script, f);
|
||||
|
||||
sampleSource.setScript(script);
|
||||
return sampleSource;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,69 +18,21 @@ import static sh.ball.gui.Gui.logger;
|
|||
|
||||
public class LuaSampleSource implements FrameSource<Vector2> {
|
||||
|
||||
private final Globals globals;
|
||||
private final Map<LuaString, LuaValue> bindings = new HashMap<>();
|
||||
private final Set<LuaString> programDefinedVariables = new HashSet<>();
|
||||
private LuaFunction lastWorkingFunction;
|
||||
private String lastWorkingTextScript;
|
||||
private LuaFunction function;
|
||||
private String textScript;
|
||||
private final LuaExecutor executor;
|
||||
private boolean active = true;
|
||||
private long step = 1;
|
||||
|
||||
public LuaSampleSource(Globals globals) {
|
||||
this.globals = globals;
|
||||
this.executor = new LuaExecutor(globals);
|
||||
}
|
||||
|
||||
public void setFunction(String textScript, LuaFunction function) {
|
||||
if (lastWorkingFunction == null) {
|
||||
lastWorkingFunction = function;
|
||||
lastWorkingTextScript = textScript;
|
||||
}
|
||||
this.function = function;
|
||||
this.textScript = textScript;
|
||||
public void setScript(String textScript) {
|
||||
executor.setScript(textScript);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2 next() {
|
||||
try {
|
||||
boolean updatedFile = false;
|
||||
|
||||
globals.setmetatable(new BindingsMetatable(bindings));
|
||||
bindings.put(LuaValue.valueOf("step"), LuaValue.valueOf((double) step));
|
||||
|
||||
LuaValue result;
|
||||
try {
|
||||
result = (LuaValue) LuaSampleSource.eval(function, globals);
|
||||
if (!lastWorkingTextScript.equals(textScript)) {
|
||||
lastWorkingFunction = function;
|
||||
lastWorkingTextScript = textScript;
|
||||
updatedFile = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.INFO, e.getMessage(), e);
|
||||
result = (LuaValue) LuaSampleSource.eval(lastWorkingFunction, globals);
|
||||
}
|
||||
step++;
|
||||
|
||||
if (updatedFile) {
|
||||
// reset variables
|
||||
step = 1;
|
||||
List<LuaString> variablesToRemove = new ArrayList<>();
|
||||
bindings.keySet().forEach(name -> {
|
||||
if (!programDefinedVariables.contains(name)) {
|
||||
variablesToRemove.add(name);
|
||||
}
|
||||
});
|
||||
variablesToRemove.forEach(bindings::remove);
|
||||
}
|
||||
|
||||
return new Vector2(result.get(1).checkdouble(), result.get(2).checkdouble());
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.INFO, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return new Vector2();
|
||||
LuaValue result = executor.execute();
|
||||
return new Vector2(result.get(1).checkdouble(), result.get(2).checkdouble());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -107,110 +59,10 @@ public class LuaSampleSource implements FrameSource<Vector2> {
|
|||
}
|
||||
|
||||
public void setVariable(String variableName, Object value) {
|
||||
programDefinedVariables.add(LuaValue.valueOf(variableName));
|
||||
bindings.put(LuaValue.valueOf(variableName), toLua(value));
|
||||
executor.setVariable(variableName, value);
|
||||
}
|
||||
|
||||
public void resetStep() {
|
||||
step = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2007 LuaJ. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit p ersons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
------------------------------
|
||||
|
||||
The below functions have all been modified by James Ball to optimise Lua parsing
|
||||
on machines with poorer performance.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
static class BindingsMetatable extends LuaTable {
|
||||
|
||||
BindingsMetatable(Map<LuaString, LuaValue> bindings) {
|
||||
this.rawset(LuaValue.INDEX, new TwoArgFunction() {
|
||||
public LuaValue call(LuaValue table, LuaValue key) {
|
||||
LuaValue value = bindings.get(key.checkstring());
|
||||
if (value == null) {
|
||||
return LuaValue.NIL;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.rawset(LuaValue.NEWINDEX, new ThreeArgFunction() {
|
||||
public LuaValue call(LuaValue table, LuaValue key, LuaValue value) {
|
||||
if (value == null || value.type() == LuaValue.TNIL) {
|
||||
bindings.remove(key.checkstring());
|
||||
} else {
|
||||
bindings.put(key.checkstring(), value);
|
||||
}
|
||||
return LuaValue.NONE;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static private LuaValue toLua(Object javaValue) {
|
||||
return javaValue == null? LuaValue.NIL:
|
||||
javaValue instanceof LuaValue? (LuaValue) javaValue:
|
||||
CoerceJavaToLua.coerce(javaValue);
|
||||
}
|
||||
|
||||
static private Object toJava(LuaValue luajValue) {
|
||||
return switch (luajValue.type()) {
|
||||
case LuaValue.TNIL -> null;
|
||||
case LuaValue.TSTRING -> luajValue.tojstring();
|
||||
case LuaValue.TUSERDATA -> luajValue.checkuserdata(Object.class);
|
||||
case LuaValue.TNUMBER -> luajValue.isinttype() ?
|
||||
(Object) luajValue.toint() :
|
||||
(Object) luajValue.todouble();
|
||||
default -> luajValue;
|
||||
};
|
||||
}
|
||||
|
||||
static private Object toJava(Varargs v) {
|
||||
final int n = v.narg();
|
||||
switch (n) {
|
||||
case 0: return null;
|
||||
case 1: return toJava(v.arg1());
|
||||
default:
|
||||
Object[] o = new Object[n];
|
||||
for (int i=0; i<n; ++i)
|
||||
o[i] = toJava(v.arg(i+1));
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
static private Object eval(LuaFunction f, Globals g) throws ScriptException {
|
||||
try {
|
||||
f = f.getClass().newInstance();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
throw new ScriptException(e);
|
||||
}
|
||||
f.initupvalue1(g);
|
||||
return toJava(f.invoke(LuaValue.NONE));
|
||||
executor.resetStep();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,12 @@
|
|||
</children>
|
||||
</AnchorPane>
|
||||
<EffectComponentGroup fx:id="depthScale" increment="0.005" label="depthScale" majorTickUnit="0.1" max="1.0" min="0.0" name="3D Perspective" type="DEPTH_3D" value="1.0" />
|
||||
<EffectComponentGroup fx:id="zPos" alwaysEnabled="true" increment="0.005" label="zPos" max="1.0" name="3D Distance" type="Z_POS_3D" value="0.1" />
|
||||
<AnchorPane prefHeight="34.0" prefWidth="602.0">
|
||||
<children>
|
||||
<Button fx:id="depthFunctionButton" layoutX="232.0" layoutY="1.0" mnemonicParsing="false" text="Modify Depth Function" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<EffectComponentGroup fx:id="zPos" alwaysEnabled="true" increment="0.005" label="zPos" max="1.0" name="3D Distance (z)" type="Z_POS_3D" value="0.1" />
|
||||
<EffectComponentGroup fx:id="rotateSpeed3D" alwaysEnabled="true" increment="0.005" label="rotateSpeed3d" majorTickUnit="0.2" max="1.0" min="-1.0" name="3D Rotate speed" type="ROTATE_SPEED_3D" value="0.0" />
|
||||
<EffectComponentGroup fx:id="rotateX" alwaysEnabled="true" increment="0.01" label="imageRotateX" majorTickUnit="0.2" max="1.0" min="-1.0" name="Rotate x" type="ROTATE_X" value="1.0" />
|
||||
<EffectComponentGroup fx:id="rotateY" alwaysEnabled="true" increment="0.01" label="imageRotateY" majorTickUnit="0.2" max="1.0" min="-1.0" name="Rotate y" type="ROTATE_Y" value="1.0" />
|
||||
|
|
|
@ -39,11 +39,11 @@
|
|||
</MenuItem>
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu mnemonicParsing="false" text="Audio">
|
||||
<Menu fx:id="audioMenu" mnemonicParsing="false" text="Audio">
|
||||
<items>
|
||||
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="Audio Device">
|
||||
<CustomMenuItem fx:id="audioDeviceMenuItem" hideOnClick="false" mnemonicParsing="false" text="Audio Device">
|
||||
<content>
|
||||
<AnchorPane>
|
||||
<AnchorPane focusTraversable="true">
|
||||
<children>
|
||||
<ComboBox fx:id="deviceComboBox" prefHeight="26.0" prefWidth="376.0" />
|
||||
</children>
|
||||
|
|
Ładowanie…
Reference in New Issue