forked from LeenkxTeam/LNXSDK
merge upstream
This commit is contained in:
commit
316441b954
@ -80,6 +80,7 @@ extern class Krom {
|
||||
static function unloadImage(image: kha.Image): Void;
|
||||
static function loadSound(file: String): Dynamic;
|
||||
static function writeAudioBuffer(buffer: js.lib.ArrayBuffer, samples: Int): Void;
|
||||
static function getSamplesPerSecond(): Int;
|
||||
static function loadBlob(file: String): js.lib.ArrayBuffer;
|
||||
|
||||
static function init(title: String, width: Int, height: Int, samplesPerPixel: Int, vSync: Bool, windowMode: Int, windowFeatures: Int, kromApi: Int): Void;
|
||||
@ -115,6 +116,7 @@ extern class Krom {
|
||||
static function screenDpi(): Int;
|
||||
static function systemId(): String;
|
||||
static function requestShutdown(): Void;
|
||||
static function displayFrequency(): Int;
|
||||
static function displayCount(): Int;
|
||||
static function displayWidth(index: Int): Int;
|
||||
static function displayHeight(index: Int): Int;
|
||||
|
@ -79,7 +79,7 @@ class Display {
|
||||
public var frequency(get, never): Int;
|
||||
|
||||
function get_frequency(): Int {
|
||||
return 60;
|
||||
return Krom.displayFrequency();
|
||||
}
|
||||
|
||||
public var pixelsPerInch(get, never): Int;
|
||||
|
@ -1,343 +1,344 @@
|
||||
package kha;
|
||||
|
||||
import kha.graphics4.TextureFormat;
|
||||
import kha.input.Gamepad;
|
||||
import kha.input.Keyboard;
|
||||
import kha.input.Mouse;
|
||||
import kha.input.MouseImpl;
|
||||
import kha.input.Pen;
|
||||
import kha.input.Surface;
|
||||
import kha.System;
|
||||
import haxe.ds.Vector;
|
||||
|
||||
class SystemImpl {
|
||||
static var start: Float;
|
||||
static var framebuffer: Framebuffer;
|
||||
static var keyboard: Keyboard;
|
||||
static var mouse: Mouse;
|
||||
static var pen: Pen;
|
||||
static var maxGamepads: Int = 4;
|
||||
static var gamepads: Array<Gamepad>;
|
||||
static var mouseLockListeners: Array<Void->Void> = [];
|
||||
|
||||
static function renderCallback(): Void {
|
||||
Scheduler.executeFrame();
|
||||
System.render([framebuffer]);
|
||||
}
|
||||
|
||||
static function dropFilesCallback(filePath: String): Void {
|
||||
System.dropFiles(filePath);
|
||||
}
|
||||
|
||||
static function copyCallback(): String {
|
||||
if (System.copyListener != null) {
|
||||
return System.copyListener();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static function cutCallback(): String {
|
||||
if (System.cutListener != null) {
|
||||
return System.cutListener();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static function pasteCallback(data: String): Void {
|
||||
if (System.pasteListener != null) {
|
||||
System.pasteListener(data);
|
||||
}
|
||||
}
|
||||
|
||||
static function foregroundCallback(): Void {
|
||||
System.foreground();
|
||||
}
|
||||
|
||||
static function resumeCallback(): Void {
|
||||
System.resume();
|
||||
}
|
||||
|
||||
static function pauseCallback(): Void {
|
||||
System.pause();
|
||||
}
|
||||
|
||||
static function backgroundCallback(): Void {
|
||||
System.background();
|
||||
}
|
||||
|
||||
static function shutdownCallback(): Void {
|
||||
System.shutdown();
|
||||
}
|
||||
|
||||
static function keyboardDownCallback(code: Int): Void {
|
||||
keyboard.sendDownEvent(cast code);
|
||||
}
|
||||
|
||||
static function keyboardUpCallback(code: Int): Void {
|
||||
keyboard.sendUpEvent(cast code);
|
||||
}
|
||||
|
||||
static function keyboardPressCallback(charCode: Int): Void {
|
||||
keyboard.sendPressEvent(String.fromCharCode(charCode));
|
||||
}
|
||||
|
||||
static function mouseDownCallback(button: Int, x: Int, y: Int): Void {
|
||||
mouse.sendDownEvent(0, button, x, y);
|
||||
}
|
||||
|
||||
static function mouseUpCallback(button: Int, x: Int, y: Int): Void {
|
||||
mouse.sendUpEvent(0, button, x, y);
|
||||
}
|
||||
|
||||
static function mouseMoveCallback(x: Int, y: Int, mx: Int, my: Int): Void {
|
||||
mouse.sendMoveEvent(0, x, y, mx, my);
|
||||
}
|
||||
|
||||
static function mouseWheelCallback(delta: Int): Void {
|
||||
mouse.sendWheelEvent(0, delta);
|
||||
}
|
||||
|
||||
static function penDownCallback(x: Int, y: Int, pressure: Float): Void {
|
||||
pen.sendDownEvent(0, x, y, pressure);
|
||||
}
|
||||
|
||||
static function penUpCallback(x: Int, y: Int, pressure: Float): Void {
|
||||
pen.sendUpEvent(0, x, y, pressure);
|
||||
}
|
||||
|
||||
static function penMoveCallback(x: Int, y: Int, pressure: Float): Void {
|
||||
pen.sendMoveEvent(0, x, y, pressure);
|
||||
}
|
||||
|
||||
static function gamepadAxisCallback(gamepad: Int, axis: Int, value: Float): Void {
|
||||
gamepads[gamepad].sendAxisEvent(axis, value);
|
||||
}
|
||||
|
||||
static function gamepadButtonCallback(gamepad: Int, button: Int, value: Float): Void {
|
||||
gamepads[gamepad].sendButtonEvent(button, value);
|
||||
}
|
||||
|
||||
static function audioCallback(samples: Int): Void {
|
||||
kha.audio2.Audio._callCallback(samples);
|
||||
var buffer = @:privateAccess kha.audio2.Audio.buffer;
|
||||
Krom.writeAudioBuffer(buffer.data.buffer, samples);
|
||||
}
|
||||
|
||||
public static function init(options: SystemOptions, callback: Window->Void): Void {
|
||||
Krom.init(options.title, options.width, options.height, options.framebuffer.samplesPerPixel, options.framebuffer.verticalSync,
|
||||
cast options.window.mode, options.window.windowFeatures, Krom.KROM_API);
|
||||
|
||||
start = Krom.getTime();
|
||||
|
||||
haxe.Log.trace = function(v: Dynamic, ?infos: haxe.PosInfos) {
|
||||
var message = haxe.Log.formatOutput(v, infos);
|
||||
Krom.log(message);
|
||||
};
|
||||
|
||||
new Window(0);
|
||||
Scheduler.init();
|
||||
Shaders.init();
|
||||
|
||||
var g4 = new kha.krom.Graphics();
|
||||
framebuffer = new Framebuffer(0, null, null, g4);
|
||||
framebuffer.init(new kha.graphics2.Graphics1(framebuffer), new kha.graphics4.Graphics2(framebuffer), g4);
|
||||
Krom.setCallback(renderCallback);
|
||||
Krom.setDropFilesCallback(dropFilesCallback);
|
||||
Krom.setCutCopyPasteCallback(cutCallback, copyCallback, pasteCallback);
|
||||
Krom.setApplicationStateCallback(foregroundCallback, resumeCallback, pauseCallback, backgroundCallback, shutdownCallback);
|
||||
|
||||
keyboard = new Keyboard();
|
||||
mouse = new MouseImpl();
|
||||
pen = new Pen();
|
||||
gamepads = new Array<Gamepad>();
|
||||
for (i in 0...maxGamepads) {
|
||||
gamepads[i] = new Gamepad(i);
|
||||
}
|
||||
|
||||
Krom.setKeyboardDownCallback(keyboardDownCallback);
|
||||
Krom.setKeyboardUpCallback(keyboardUpCallback);
|
||||
Krom.setKeyboardPressCallback(keyboardPressCallback);
|
||||
Krom.setMouseDownCallback(mouseDownCallback);
|
||||
Krom.setMouseUpCallback(mouseUpCallback);
|
||||
Krom.setMouseMoveCallback(mouseMoveCallback);
|
||||
Krom.setMouseWheelCallback(mouseWheelCallback);
|
||||
Krom.setPenDownCallback(penDownCallback);
|
||||
Krom.setPenUpCallback(penUpCallback);
|
||||
Krom.setPenMoveCallback(penMoveCallback);
|
||||
Krom.setGamepadAxisCallback(gamepadAxisCallback);
|
||||
Krom.setGamepadButtonCallback(gamepadButtonCallback);
|
||||
|
||||
kha.audio2.Audio._init();
|
||||
kha.audio1.Audio._init();
|
||||
Krom.setAudioCallback(audioCallback);
|
||||
|
||||
Scheduler.start();
|
||||
|
||||
callback(Window.get(0));
|
||||
}
|
||||
|
||||
public static function initEx(title: String, options: Array<WindowOptions>, windowCallback: Int->Void, callback: Void->Void): Void {}
|
||||
|
||||
static function translateWindowMode(value: Null<WindowMode>): Int {
|
||||
if (value == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return switch (value) {
|
||||
case Windowed: 0;
|
||||
case Fullscreen: 1;
|
||||
case ExclusiveFullscreen: 2;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getScreenRotation(): ScreenRotation {
|
||||
return ScreenRotation.RotationNone;
|
||||
}
|
||||
|
||||
public static function getTime(): Float {
|
||||
return Krom.getTime() - start;
|
||||
}
|
||||
|
||||
public static function getVsync(): Bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getRefreshRate(): Int {
|
||||
return 60;
|
||||
}
|
||||
|
||||
public static function getSystemId(): String {
|
||||
return Krom.systemId();
|
||||
}
|
||||
|
||||
public static function vibrate(ms: Int): Void {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
public static function getLanguage(): String {
|
||||
return "en"; // TODO: Implement
|
||||
}
|
||||
|
||||
public static function requestShutdown(): Bool {
|
||||
Krom.requestShutdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getMouse(num: Int): Mouse {
|
||||
return mouse;
|
||||
}
|
||||
|
||||
public static function getPen(num: Int): Pen {
|
||||
return pen;
|
||||
}
|
||||
|
||||
public static function getKeyboard(num: Int): Keyboard {
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
public static function lockMouse(): Void {
|
||||
if (!isMouseLocked()) {
|
||||
Krom.lockMouse();
|
||||
for (listener in mouseLockListeners) {
|
||||
listener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function unlockMouse(): Void {
|
||||
if (isMouseLocked()) {
|
||||
Krom.unlockMouse();
|
||||
for (listener in mouseLockListeners) {
|
||||
listener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function canLockMouse(): Bool {
|
||||
return Krom.canLockMouse();
|
||||
}
|
||||
|
||||
public static function isMouseLocked(): Bool {
|
||||
return Krom.isMouseLocked();
|
||||
}
|
||||
|
||||
public static function notifyOfMouseLockChange(func: Void->Void, error: Void->Void): Void {
|
||||
if (canLockMouse() && func != null) {
|
||||
mouseLockListeners.push(func);
|
||||
}
|
||||
}
|
||||
|
||||
public static function removeFromMouseLockChange(func: Void->Void, error: Void->Void): Void {
|
||||
if (canLockMouse() && func != null) {
|
||||
mouseLockListeners.remove(func);
|
||||
}
|
||||
}
|
||||
|
||||
public static function hideSystemCursor(): Void {
|
||||
Krom.showMouse(false);
|
||||
}
|
||||
|
||||
public static function showSystemCursor(): Void {
|
||||
Krom.showMouse(true);
|
||||
}
|
||||
|
||||
static function unload(): Void {}
|
||||
|
||||
public static function canSwitchFullscreen(): Bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function isFullscreen(): Bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function requestFullscreen(): Void {}
|
||||
|
||||
public static function exitFullscreen(): Void {}
|
||||
|
||||
public static function notifyOfFullscreenChange(func: Void->Void, error: Void->Void): Void {}
|
||||
|
||||
public static function removeFromFullscreenChange(func: Void->Void, error: Void->Void): Void {}
|
||||
|
||||
public static function changeResolution(width: Int, height: Int): Void {}
|
||||
|
||||
public static function setKeepScreenOn(on: Bool): Void {}
|
||||
|
||||
public static function loadUrl(url: String): Void {}
|
||||
|
||||
public static function getGamepadId(index: Int): String {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static function getGamepadVendor(index: Int): String {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static function setGamepadRumble(index: Int, leftAmount: Float, rightAmount: Float): Void {}
|
||||
|
||||
public static function safeZone(): Float {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public static function login(): Void {}
|
||||
|
||||
public static function automaticSafeZone(): Bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function setSafeZone(value: Float): Void {}
|
||||
|
||||
public static function unlockAchievement(id: Int): Void {}
|
||||
|
||||
public static function waitingForLogin(): Bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function disallowUserChange(): Void {}
|
||||
|
||||
public static function allowUserChange(): Void {}
|
||||
}
|
||||
package kha;
|
||||
|
||||
import kha.graphics4.TextureFormat;
|
||||
import kha.input.Gamepad;
|
||||
import kha.input.Keyboard;
|
||||
import kha.input.Mouse;
|
||||
import kha.input.MouseImpl;
|
||||
import kha.input.Pen;
|
||||
import kha.input.Surface;
|
||||
import kha.System;
|
||||
import haxe.ds.Vector;
|
||||
|
||||
class SystemImpl {
|
||||
static var start: Float;
|
||||
static var framebuffer: Framebuffer;
|
||||
static var keyboard: Keyboard;
|
||||
static var mouse: Mouse;
|
||||
static var pen: Pen;
|
||||
static var maxGamepads: Int = 4;
|
||||
static var gamepads: Array<Gamepad>;
|
||||
static var mouseLockListeners: Array<Void->Void> = [];
|
||||
|
||||
static function renderCallback(): Void {
|
||||
Scheduler.executeFrame();
|
||||
System.render([framebuffer]);
|
||||
}
|
||||
|
||||
static function dropFilesCallback(filePath: String): Void {
|
||||
System.dropFiles(filePath);
|
||||
}
|
||||
|
||||
static function copyCallback(): String {
|
||||
if (System.copyListener != null) {
|
||||
return System.copyListener();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static function cutCallback(): String {
|
||||
if (System.cutListener != null) {
|
||||
return System.cutListener();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static function pasteCallback(data: String): Void {
|
||||
if (System.pasteListener != null) {
|
||||
System.pasteListener(data);
|
||||
}
|
||||
}
|
||||
|
||||
static function foregroundCallback(): Void {
|
||||
System.foreground();
|
||||
}
|
||||
|
||||
static function resumeCallback(): Void {
|
||||
System.resume();
|
||||
}
|
||||
|
||||
static function pauseCallback(): Void {
|
||||
System.pause();
|
||||
}
|
||||
|
||||
static function backgroundCallback(): Void {
|
||||
System.background();
|
||||
}
|
||||
|
||||
static function shutdownCallback(): Void {
|
||||
System.shutdown();
|
||||
}
|
||||
|
||||
static function keyboardDownCallback(code: Int): Void {
|
||||
keyboard.sendDownEvent(cast code);
|
||||
}
|
||||
|
||||
static function keyboardUpCallback(code: Int): Void {
|
||||
keyboard.sendUpEvent(cast code);
|
||||
}
|
||||
|
||||
static function keyboardPressCallback(charCode: Int): Void {
|
||||
keyboard.sendPressEvent(String.fromCharCode(charCode));
|
||||
}
|
||||
|
||||
static function mouseDownCallback(button: Int, x: Int, y: Int): Void {
|
||||
mouse.sendDownEvent(0, button, x, y);
|
||||
}
|
||||
|
||||
static function mouseUpCallback(button: Int, x: Int, y: Int): Void {
|
||||
mouse.sendUpEvent(0, button, x, y);
|
||||
}
|
||||
|
||||
static function mouseMoveCallback(x: Int, y: Int, mx: Int, my: Int): Void {
|
||||
mouse.sendMoveEvent(0, x, y, mx, my);
|
||||
}
|
||||
|
||||
static function mouseWheelCallback(delta: Int): Void {
|
||||
mouse.sendWheelEvent(0, delta);
|
||||
}
|
||||
|
||||
static function penDownCallback(x: Int, y: Int, pressure: Float): Void {
|
||||
pen.sendDownEvent(0, x, y, pressure);
|
||||
}
|
||||
|
||||
static function penUpCallback(x: Int, y: Int, pressure: Float): Void {
|
||||
pen.sendUpEvent(0, x, y, pressure);
|
||||
}
|
||||
|
||||
static function penMoveCallback(x: Int, y: Int, pressure: Float): Void {
|
||||
pen.sendMoveEvent(0, x, y, pressure);
|
||||
}
|
||||
|
||||
static function gamepadAxisCallback(gamepad: Int, axis: Int, value: Float): Void {
|
||||
gamepads[gamepad].sendAxisEvent(axis, value);
|
||||
}
|
||||
|
||||
static function gamepadButtonCallback(gamepad: Int, button: Int, value: Float): Void {
|
||||
gamepads[gamepad].sendButtonEvent(button, value);
|
||||
}
|
||||
|
||||
static function audioCallback(samples: Int): Void {
|
||||
kha.audio2.Audio._callCallback(samples);
|
||||
var buffer = @:privateAccess kha.audio2.Audio.buffer;
|
||||
Krom.writeAudioBuffer(buffer.data.buffer, samples);
|
||||
}
|
||||
|
||||
public static function init(options: SystemOptions, callback: Window->Void): Void {
|
||||
Krom.init(options.title, options.width, options.height, options.framebuffer.samplesPerPixel, options.framebuffer.verticalSync,
|
||||
cast options.window.mode, options.window.windowFeatures, Krom.KROM_API);
|
||||
|
||||
start = Krom.getTime();
|
||||
|
||||
haxe.Log.trace = function(v: Dynamic, ?infos: haxe.PosInfos) {
|
||||
var message = haxe.Log.formatOutput(v, infos);
|
||||
Krom.log(message);
|
||||
};
|
||||
|
||||
new Window(0);
|
||||
Scheduler.init();
|
||||
Shaders.init();
|
||||
|
||||
var g4 = new kha.krom.Graphics();
|
||||
framebuffer = new Framebuffer(0, null, null, g4);
|
||||
framebuffer.init(new kha.graphics2.Graphics1(framebuffer), new kha.graphics4.Graphics2(framebuffer), g4);
|
||||
Krom.setCallback(renderCallback);
|
||||
Krom.setDropFilesCallback(dropFilesCallback);
|
||||
Krom.setCutCopyPasteCallback(cutCallback, copyCallback, pasteCallback);
|
||||
Krom.setApplicationStateCallback(foregroundCallback, resumeCallback, pauseCallback, backgroundCallback, shutdownCallback);
|
||||
|
||||
keyboard = new Keyboard();
|
||||
mouse = new MouseImpl();
|
||||
pen = new Pen();
|
||||
gamepads = new Array<Gamepad>();
|
||||
for (i in 0...maxGamepads) {
|
||||
gamepads[i] = new Gamepad(i);
|
||||
}
|
||||
|
||||
Krom.setKeyboardDownCallback(keyboardDownCallback);
|
||||
Krom.setKeyboardUpCallback(keyboardUpCallback);
|
||||
Krom.setKeyboardPressCallback(keyboardPressCallback);
|
||||
Krom.setMouseDownCallback(mouseDownCallback);
|
||||
Krom.setMouseUpCallback(mouseUpCallback);
|
||||
Krom.setMouseMoveCallback(mouseMoveCallback);
|
||||
Krom.setMouseWheelCallback(mouseWheelCallback);
|
||||
Krom.setPenDownCallback(penDownCallback);
|
||||
Krom.setPenUpCallback(penUpCallback);
|
||||
Krom.setPenMoveCallback(penMoveCallback);
|
||||
Krom.setGamepadAxisCallback(gamepadAxisCallback);
|
||||
Krom.setGamepadButtonCallback(gamepadButtonCallback);
|
||||
|
||||
kha.audio2.Audio.samplesPerSecond = Krom.getSamplesPerSecond();
|
||||
kha.audio1.Audio._init();
|
||||
kha.audio2.Audio._init();
|
||||
Krom.setAudioCallback(audioCallback);
|
||||
|
||||
Scheduler.start();
|
||||
|
||||
callback(Window.get(0));
|
||||
}
|
||||
|
||||
public static function initEx(title: String, options: Array<WindowOptions>, windowCallback: Int->Void, callback: Void->Void): Void {}
|
||||
|
||||
static function translateWindowMode(value: Null<WindowMode>): Int {
|
||||
if (value == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return switch (value) {
|
||||
case Windowed: 0;
|
||||
case Fullscreen: 1;
|
||||
case ExclusiveFullscreen: 2;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getScreenRotation(): ScreenRotation {
|
||||
return ScreenRotation.RotationNone;
|
||||
}
|
||||
|
||||
public static function getTime(): Float {
|
||||
return Krom.getTime() - start;
|
||||
}
|
||||
|
||||
public static function getVsync(): Bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getRefreshRate(): Int {
|
||||
return Krom.displayFrequency();
|
||||
}
|
||||
|
||||
public static function getSystemId(): String {
|
||||
return Krom.systemId();
|
||||
}
|
||||
|
||||
public static function vibrate(ms: Int): Void {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
public static function getLanguage(): String {
|
||||
return "en"; // TODO: Implement
|
||||
}
|
||||
|
||||
public static function requestShutdown(): Bool {
|
||||
Krom.requestShutdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getMouse(num: Int): Mouse {
|
||||
return mouse;
|
||||
}
|
||||
|
||||
public static function getPen(num: Int): Pen {
|
||||
return pen;
|
||||
}
|
||||
|
||||
public static function getKeyboard(num: Int): Keyboard {
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
public static function lockMouse(): Void {
|
||||
if (!isMouseLocked()) {
|
||||
Krom.lockMouse();
|
||||
for (listener in mouseLockListeners) {
|
||||
listener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function unlockMouse(): Void {
|
||||
if (isMouseLocked()) {
|
||||
Krom.unlockMouse();
|
||||
for (listener in mouseLockListeners) {
|
||||
listener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function canLockMouse(): Bool {
|
||||
return Krom.canLockMouse();
|
||||
}
|
||||
|
||||
public static function isMouseLocked(): Bool {
|
||||
return Krom.isMouseLocked();
|
||||
}
|
||||
|
||||
public static function notifyOfMouseLockChange(func: Void->Void, error: Void->Void): Void {
|
||||
if (canLockMouse() && func != null) {
|
||||
mouseLockListeners.push(func);
|
||||
}
|
||||
}
|
||||
|
||||
public static function removeFromMouseLockChange(func: Void->Void, error: Void->Void): Void {
|
||||
if (canLockMouse() && func != null) {
|
||||
mouseLockListeners.remove(func);
|
||||
}
|
||||
}
|
||||
|
||||
public static function hideSystemCursor(): Void {
|
||||
Krom.showMouse(false);
|
||||
}
|
||||
|
||||
public static function showSystemCursor(): Void {
|
||||
Krom.showMouse(true);
|
||||
}
|
||||
|
||||
static function unload(): Void {}
|
||||
|
||||
public static function canSwitchFullscreen(): Bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function isFullscreen(): Bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function requestFullscreen(): Void {}
|
||||
|
||||
public static function exitFullscreen(): Void {}
|
||||
|
||||
public static function notifyOfFullscreenChange(func: Void->Void, error: Void->Void): Void {}
|
||||
|
||||
public static function removeFromFullscreenChange(func: Void->Void, error: Void->Void): Void {}
|
||||
|
||||
public static function changeResolution(width: Int, height: Int): Void {}
|
||||
|
||||
public static function setKeepScreenOn(on: Bool): Void {}
|
||||
|
||||
public static function loadUrl(url: String): Void {}
|
||||
|
||||
public static function getGamepadId(index: Int): String {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static function getGamepadVendor(index: Int): String {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static function setGamepadRumble(index: Int, leftAmount: Float, rightAmount: Float): Void {}
|
||||
|
||||
public static function safeZone(): Float {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public static function login(): Void {}
|
||||
|
||||
public static function automaticSafeZone(): Bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function setSafeZone(value: Float): Void {}
|
||||
|
||||
public static function unlockAchievement(id: Int): Void {}
|
||||
|
||||
public static function waitingForLogin(): Bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function disallowUserChange(): Void {}
|
||||
|
||||
public static function allowUserChange(): Void {}
|
||||
}
|
||||
|
@ -1,57 +1,56 @@
|
||||
package kha.audio2;
|
||||
|
||||
import kha.Sound;
|
||||
import kha.internal.IntBox;
|
||||
|
||||
class Audio {
|
||||
public static var disableGcInteractions = false;
|
||||
static var intBox: IntBox = new IntBox(0);
|
||||
static var buffer: Buffer;
|
||||
|
||||
public static function _init() {
|
||||
var bufferSize = 1024 * 2;
|
||||
buffer = new Buffer(bufferSize * 4, 2, 44100);
|
||||
Audio.samplesPerSecond = 44100;
|
||||
}
|
||||
|
||||
public static function _callCallback(samples: Int): Void {
|
||||
if (buffer == null)
|
||||
return;
|
||||
if (audioCallback != null) {
|
||||
intBox.value = samples;
|
||||
audioCallback(intBox, buffer);
|
||||
}
|
||||
else {
|
||||
for (i in 0...samples) {
|
||||
buffer.data.set(buffer.writeLocation, 0);
|
||||
buffer.writeLocation += 1;
|
||||
if (buffer.writeLocation >= buffer.size) {
|
||||
buffer.writeLocation = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function _readSample(): Float {
|
||||
if (buffer == null)
|
||||
return 0;
|
||||
var value = buffer.data.get(buffer.readLocation);
|
||||
buffer.readLocation += 1;
|
||||
if (buffer.readLocation >= buffer.size) {
|
||||
buffer.readLocation = 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static var samplesPerSecond: Int;
|
||||
|
||||
public static var audioCallback: IntBox->Buffer->Void;
|
||||
|
||||
public static function play(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
package kha.audio2;
|
||||
|
||||
import kha.Sound;
|
||||
import kha.internal.IntBox;
|
||||
|
||||
class Audio {
|
||||
public static var disableGcInteractions = false;
|
||||
static var intBox: IntBox = new IntBox(0);
|
||||
static var buffer: Buffer;
|
||||
|
||||
public static function _init() {
|
||||
var bufferSize = 1024 * 2;
|
||||
buffer = new Buffer(bufferSize * 4, 2, samplesPerSecond);
|
||||
}
|
||||
|
||||
public static function _callCallback(samples: Int): Void {
|
||||
if (buffer == null)
|
||||
return;
|
||||
if (audioCallback != null) {
|
||||
intBox.value = samples;
|
||||
audioCallback(intBox, buffer);
|
||||
}
|
||||
else {
|
||||
for (i in 0...samples) {
|
||||
buffer.data.set(buffer.writeLocation, 0);
|
||||
buffer.writeLocation += 1;
|
||||
if (buffer.writeLocation >= buffer.size) {
|
||||
buffer.writeLocation = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function _readSample(): FastFloat {
|
||||
if (buffer == null)
|
||||
return 0;
|
||||
var value = buffer.data.get(buffer.readLocation);
|
||||
++buffer.readLocation;
|
||||
if (buffer.readLocation >= buffer.size) {
|
||||
buffer.readLocation = 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static var samplesPerSecond: Int;
|
||||
|
||||
public static var audioCallback: IntBox->Buffer->Void;
|
||||
|
||||
public static function play(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class Graphics implements kha.graphics4.Graphics {
|
||||
}
|
||||
|
||||
public function refreshRate(): Int {
|
||||
return 60;
|
||||
return Krom.displayFrequency();
|
||||
}
|
||||
|
||||
public function clear(?color: Color, ?depth: Float, ?stencil: Int): Void {
|
||||
|
File diff suppressed because it is too large
Load Diff
BIN
Krom/Krom.exe
BIN
Krom/Krom.exe
Binary file not shown.
Binary file not shown.
@ -310,9 +310,9 @@ class LeenkxAddonPreferences(AddonPreferences):
|
||||
layout.label(text="Welcome to Leenkx!")
|
||||
|
||||
# Compare version Blender and Leenkx (major, minor)
|
||||
if bpy.app.version[0] != 4 or bpy.app.version[1] != 2:
|
||||
if bpy.app.version[:2] not in [(4, 4), (4, 2), (3, 6), (3, 3)]:
|
||||
box = layout.box().column()
|
||||
box.label(text="Warning: For Leenkx to work correctly, use a Blender LTS version such as 4.2 | 3.6 | 3.3")
|
||||
box.label(text="Warning: For Leenkx to work correctly, use a Blender LTS version")
|
||||
|
||||
layout.prop(self, "sdk_path")
|
||||
sdk_path = get_sdk_path(context)
|
||||
|
@ -51,6 +51,7 @@ class ParticleSystem {
|
||||
seed = pref.seed;
|
||||
particles = [];
|
||||
ready = false;
|
||||
|
||||
Data.getParticle(sceneName, pref.particle, function(b: ParticleData) {
|
||||
data = b;
|
||||
r = data.raw;
|
||||
@ -70,7 +71,13 @@ class ParticleSystem {
|
||||
lifetime = r.lifetime / frameRate;
|
||||
animtime = (r.frame_end - r.frame_start) / frameRate;
|
||||
spawnRate = ((r.frame_end - r.frame_start) / r.count) / frameRate;
|
||||
for (i in 0...r.count) particles.push(new Particle(i));
|
||||
|
||||
for (i in 0...r.count) {
|
||||
var particle = new Particle(i);
|
||||
particle.sr = 1 - Math.random() * r.size_random;
|
||||
particles.push(particle);
|
||||
}
|
||||
|
||||
ready = true;
|
||||
});
|
||||
}
|
||||
@ -108,7 +115,7 @@ class ParticleSystem {
|
||||
}
|
||||
|
||||
// Animate
|
||||
time += Time.realDelta * speed;
|
||||
time += Time.delta * speed;
|
||||
lap = Std.int(time / animtime);
|
||||
lapTime = time - lap * animtime;
|
||||
count = Std.int(lapTime / spawnRate);
|
||||
@ -143,7 +150,7 @@ class ParticleSystem {
|
||||
}
|
||||
|
||||
function setupGeomGpu(object: MeshObject, owner: MeshObject) {
|
||||
var instancedData = new Float32Array(particles.length * 3);
|
||||
var instancedData = new Float32Array(particles.length * 6);
|
||||
var i = 0;
|
||||
|
||||
var normFactor = 1 / 32767; // pa.values are not normalized
|
||||
@ -162,6 +169,10 @@ class ParticleSystem {
|
||||
instancedData.set(i, pa.values[j * pa.size ] * normFactor * scaleFactor.x); i++;
|
||||
instancedData.set(i, pa.values[j * pa.size + 1] * normFactor * scaleFactor.y); i++;
|
||||
instancedData.set(i, pa.values[j * pa.size + 2] * normFactor * scaleFactor.z); i++;
|
||||
|
||||
instancedData.set(i, p.sr); i++;
|
||||
instancedData.set(i, p.sr); i++;
|
||||
instancedData.set(i, p.sr); i++;
|
||||
}
|
||||
|
||||
case 1: // Face
|
||||
@ -185,6 +196,10 @@ class ParticleSystem {
|
||||
instancedData.set(i, pos.x * normFactor * scaleFactor.x); i++;
|
||||
instancedData.set(i, pos.y * normFactor * scaleFactor.y); i++;
|
||||
instancedData.set(i, pos.z * normFactor * scaleFactor.z); i++;
|
||||
|
||||
instancedData.set(i, p.sr); i++;
|
||||
instancedData.set(i, p.sr); i++;
|
||||
instancedData.set(i, p.sr); i++;
|
||||
}
|
||||
|
||||
case 2: // Volume
|
||||
@ -195,9 +210,13 @@ class ParticleSystem {
|
||||
instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.x); i++;
|
||||
instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.y); i++;
|
||||
instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.z); i++;
|
||||
|
||||
instancedData.set(i, p.sr); i++;
|
||||
instancedData.set(i, p.sr); i++;
|
||||
instancedData.set(i, p.sr); i++;
|
||||
}
|
||||
}
|
||||
object.data.geom.setupInstanced(instancedData, 1, Usage.StaticUsage);
|
||||
object.data.geom.setupInstanced(instancedData, 3, Usage.StaticUsage);
|
||||
}
|
||||
|
||||
function fhash(n: Int): Float {
|
||||
@ -236,9 +255,10 @@ class ParticleSystem {
|
||||
|
||||
class Particle {
|
||||
public var i: Int;
|
||||
public var x = 0.0;
|
||||
public var y = 0.0;
|
||||
public var z = 0.0;
|
||||
public var px = 0.0;
|
||||
public var py = 0.0;
|
||||
public var pz = 0.0;
|
||||
public var sr = 1.0; // Size random
|
||||
public var cameraDistance: Float;
|
||||
|
||||
public function new(i: Int) {
|
||||
|
@ -2,9 +2,11 @@ package leenkx.logicnode;
|
||||
|
||||
import iron.object.Object;
|
||||
|
||||
#if lnx_physics
|
||||
#if lnx_bullet
|
||||
import leenkx.trait.physics.PhysicsConstraint;
|
||||
import leenkx.trait.physics.bullet.PhysicsConstraint.ConstraintType;
|
||||
#elseif lnx_oimo
|
||||
// TODO
|
||||
#end
|
||||
|
||||
class AddPhysicsConstraintNode extends LogicNode {
|
||||
@ -25,7 +27,7 @@ class AddPhysicsConstraintNode extends LogicNode {
|
||||
|
||||
if (pivotObject == null || rb1 == null || rb2 == null) return;
|
||||
|
||||
#if lnx_physics
|
||||
#if lnx_bullet
|
||||
|
||||
var disableCollisions: Bool = inputs[4].get();
|
||||
var breakable: Bool = inputs[5].get();
|
||||
@ -108,6 +110,8 @@ class AddPhysicsConstraintNode extends LogicNode {
|
||||
}
|
||||
pivotObject.addTrait(con);
|
||||
}
|
||||
#elseif lnx_oimo
|
||||
// TODO
|
||||
#end
|
||||
runOutput(0);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import iron.object.Object;
|
||||
|
||||
#if lnx_physics
|
||||
import leenkx.trait.physics.RigidBody;
|
||||
import leenkx.trait.physics.bullet.RigidBody.Shape;
|
||||
import leenkx.trait.physics.RigidBody.Shape;
|
||||
#end
|
||||
|
||||
|
||||
|
26
leenkx/Sources/leenkx/logicnode/ArrayIndexListNode.hx
Normal file
26
leenkx/Sources/leenkx/logicnode/ArrayIndexListNode.hx
Normal file
@ -0,0 +1,26 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
class ArrayIndexListNode extends LogicNode {
|
||||
|
||||
public function new(tree: LogicTree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
override function get(from: Int): Dynamic {
|
||||
var array: Array<Dynamic> = inputs[0].get();
|
||||
array = array.map(item -> Std.string(item));
|
||||
var value: Dynamic = inputs[1].get();
|
||||
var from: Int = 0;
|
||||
|
||||
var arrayList: Array<Int> = [];
|
||||
|
||||
var index: Int = array.indexOf(Std.string(value), from);
|
||||
|
||||
while(index != -1){
|
||||
arrayList.push(index);
|
||||
index = array.indexOf(Std.string(value), index+1);
|
||||
}
|
||||
|
||||
return arrayList;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
#if lnx_physics
|
||||
import leenkx.trait.physics.bullet.PhysicsWorld;
|
||||
import leenkx.trait.physics.PhysicsWorld;
|
||||
#end
|
||||
import leenkx.trait.navigation.Navigation;
|
||||
import iron.object.Object;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package leenkx.logicnode;
|
||||
|
||||
#if lnx_physics
|
||||
import leenkx.trait.physics.bullet.PhysicsConstraint.ConstraintAxis;
|
||||
import leenkx.trait.physics.PhysicsConstraint.ConstraintAxis;
|
||||
#end
|
||||
|
||||
class PhysicsConstraintNode extends LogicNode {
|
||||
|
@ -10,6 +10,10 @@ class KinematicCharacterController extends iron.Trait { public function new() {
|
||||
|
||||
typedef KinematicCharacterController = leenkx.trait.physics.bullet.KinematicCharacterController;
|
||||
|
||||
#else
|
||||
|
||||
typedef KinematicCharacterController = leenkx.trait.physics.oimo.KinematicCharacterController;
|
||||
|
||||
#end
|
||||
|
||||
#end
|
||||
|
@ -3,17 +3,16 @@ package leenkx.trait.physics;
|
||||
#if (!lnx_physics)
|
||||
|
||||
class PhysicsConstraint extends iron.Trait { public function new() { super(); } }
|
||||
@:enum abstract ConstraintAxis(Int) from Int to Int { }
|
||||
|
||||
#else
|
||||
|
||||
#if lnx_bullet
|
||||
|
||||
typedef PhysicsConstraint = leenkx.trait.physics.bullet.PhysicsConstraint;
|
||||
|
||||
typedef ConstraintAxis = leenkx.trait.physics.bullet.PhysicsConstraint.ConstraintAxis;
|
||||
#else
|
||||
|
||||
typedef PhysicsConstraint = leenkx.trait.physics.oimo.PhysicsConstraint;
|
||||
|
||||
typedef ConstraintAxis = leenkx.trait.physics.oimo.PhysicsConstraint.ConstraintAxis;
|
||||
#end
|
||||
|
||||
#end
|
||||
|
@ -2,6 +2,7 @@ package leenkx.trait.physics;
|
||||
|
||||
#if (!lnx_physics)
|
||||
|
||||
class Hit { }
|
||||
class PhysicsWorld extends iron.Trait { public function new() { super(); } }
|
||||
|
||||
#else
|
||||
@ -9,11 +10,11 @@ class PhysicsWorld extends iron.Trait { public function new() { super(); } }
|
||||
#if lnx_bullet
|
||||
|
||||
typedef PhysicsWorld = leenkx.trait.physics.bullet.PhysicsWorld;
|
||||
|
||||
typedef Hit = leenkx.trait.physics.bullet.PhysicsWorld.Hit;
|
||||
#else
|
||||
|
||||
typedef PhysicsWorld = leenkx.trait.physics.oimo.PhysicsWorld;
|
||||
|
||||
typedef Hit = leenkx.trait.physics.oimo.PhysicsWorld.Hit;
|
||||
#end
|
||||
|
||||
#end
|
||||
|
@ -3,17 +3,20 @@ package leenkx.trait.physics;
|
||||
#if (!lnx_physics)
|
||||
|
||||
class RigidBody extends iron.Trait { public function new() { super(); } }
|
||||
@:enum abstract Shape(Int) from Int to Int { }
|
||||
|
||||
#else
|
||||
|
||||
#if lnx_bullet
|
||||
|
||||
typedef RigidBody = leenkx.trait.physics.bullet.RigidBody;
|
||||
|
||||
typedef Shape = leenkx.trait.physics.bullet.RigidBody.Shape;
|
||||
|
||||
#else
|
||||
|
||||
typedef RigidBody = leenkx.trait.physics.oimo.RigidBody;
|
||||
|
||||
typedef Shape = leenkx.trait.physics.oimo.RigidBody.Shape;
|
||||
|
||||
#end
|
||||
|
||||
#end
|
||||
|
@ -1,5 +1,8 @@
|
||||
package leenkx.trait.physics.bullet;
|
||||
|
||||
#if lnx_bullet
|
||||
import leenkx.trait.physics.bullet.PhysicsWorld.DebugDrawMode;
|
||||
|
||||
import bullet.Bt.Vector3;
|
||||
|
||||
import kha.FastFloat;
|
||||
@ -18,15 +21,21 @@ class DebugDrawHelper {
|
||||
static inline var contactPointNormalColor = 0xffffffff;
|
||||
static inline var contactPointDrawLifetime = true;
|
||||
|
||||
final rayCastColor: Vec4 = new Vec4(0.0, 1.0, 0.0);
|
||||
final rayCastHitColor: Vec4 = new Vec4(1.0, 0.0, 0.0);
|
||||
final rayCastHitPointColor: Vec4 = new Vec4(1.0, 1.0, 0.0);
|
||||
|
||||
final physicsWorld: PhysicsWorld;
|
||||
final lines: Array<LineData> = [];
|
||||
final texts: Array<TextData> = [];
|
||||
var font: kha.Font = null;
|
||||
|
||||
var debugMode: PhysicsWorld.DebugDrawMode = NoDebug;
|
||||
var rayCasts:Array<TRayCastData> = [];
|
||||
var debugDrawMode: DebugDrawMode = NoDebug;
|
||||
|
||||
public function new(physicsWorld: PhysicsWorld) {
|
||||
public function new(physicsWorld: PhysicsWorld, debugDrawMode: DebugDrawMode) {
|
||||
this.physicsWorld = physicsWorld;
|
||||
this.debugDrawMode = debugDrawMode;
|
||||
|
||||
#if lnx_ui
|
||||
iron.data.Data.getFont(Canvas.defaultFontName, function(defaultFont: kha.Font) {
|
||||
@ -35,6 +44,11 @@ class DebugDrawHelper {
|
||||
#end
|
||||
|
||||
iron.App.notifyOnRender2D(onRender);
|
||||
if (debugDrawMode & DrawRayCast != 0) {
|
||||
iron.App.notifyOnUpdate(function () {
|
||||
rayCasts.resize(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function drawLine(from: bullet.Bt.Vector3, to: bullet.Bt.Vector3, color: bullet.Bt.Vector3) {
|
||||
@ -63,25 +77,6 @@ class DebugDrawHelper {
|
||||
}
|
||||
}
|
||||
|
||||
// Draws raycast in its own function because
|
||||
// something is conflicting with the btVector3 and JS pointer wrapping
|
||||
public function drawRayCast(fx:FastFloat, fy:FastFloat, fz:FastFloat, tx:FastFloat, ty:FastFloat, tz:FastFloat, r:FastFloat, g:FastFloat, b:FastFloat) {
|
||||
final fromScreenSpace = worldToScreenFast(new Vec4(fx, fy, fz, 1.0));
|
||||
final toScreenSpace = worldToScreenFast(new Vec4(tx, ty, tz, 1.0));
|
||||
|
||||
// TO DO: May still go off screen sides.
|
||||
if (fromScreenSpace.w == 1 || toScreenSpace.w == 1) {
|
||||
final color = kha.Color.fromFloats(r, g, b, 1.0);
|
||||
lines.push({
|
||||
fromX: fromScreenSpace.x,
|
||||
fromY: fromScreenSpace.y,
|
||||
toX: toScreenSpace.x,
|
||||
toY: toScreenSpace.y,
|
||||
color: color
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function drawContactPoint(pointOnB: Vector3, normalOnB: Vector3, distance: kha.FastFloat, lifeTime: Int, color: Vector3) {
|
||||
#if js
|
||||
pointOnB = js.Syntax.code("Ammo.wrapPointer({0}, Ammo.btVector3)", pointOnB);
|
||||
@ -126,7 +121,62 @@ class DebugDrawHelper {
|
||||
x: contactPointScreenSpace.x,
|
||||
y: contactPointScreenSpace.y,
|
||||
color: color,
|
||||
text: Std.string(lifeTime),
|
||||
text: Std.string(lifeTime), // lifeTime: number of frames the contact point existed
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function rayCast(rayCastData:TRayCastData) {
|
||||
rayCasts.push(rayCastData);
|
||||
}
|
||||
|
||||
function drawRayCast(f: Vec4, t: Vec4, hit: Bool) {
|
||||
final from = worldToScreenFast(f.clone());
|
||||
final to = worldToScreenFast(t.clone());
|
||||
var c: kha.Color;
|
||||
|
||||
if (from.w == 1 && to.w == 1) {
|
||||
if (hit) c = kha.Color.fromFloats(rayCastHitColor.x, rayCastHitColor.y, rayCastHitColor.z);
|
||||
else c = kha.Color.fromFloats(rayCastColor.x, rayCastColor.y, rayCastColor.z);
|
||||
|
||||
lines.push({
|
||||
fromX: from.x,
|
||||
fromY: from.y,
|
||||
toX: to.x,
|
||||
toY: to.y,
|
||||
color: c
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function drawHitPoint(hp: Vec4) {
|
||||
final hitPoint = worldToScreenFast(hp.clone());
|
||||
final c = kha.Color.fromFloats(rayCastHitPointColor.x, rayCastHitPointColor.y, rayCastHitPointColor.z);
|
||||
|
||||
if (hitPoint.w == 1) {
|
||||
lines.push({
|
||||
fromX: hitPoint.x - contactPointSizePx,
|
||||
fromY: hitPoint.y - contactPointSizePx,
|
||||
toX: hitPoint.x + contactPointSizePx,
|
||||
toY: hitPoint.y + contactPointSizePx,
|
||||
color: c
|
||||
});
|
||||
|
||||
lines.push({
|
||||
fromX: hitPoint.x - contactPointSizePx,
|
||||
fromY: hitPoint.y + contactPointSizePx,
|
||||
toX: hitPoint.x + contactPointSizePx,
|
||||
toY: hitPoint.y - contactPointSizePx,
|
||||
color: c
|
||||
});
|
||||
|
||||
if (font != null) {
|
||||
texts.push({
|
||||
x: hitPoint.x,
|
||||
y: hitPoint.y,
|
||||
color: c,
|
||||
text: 'RAYCAST HIT'
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -155,13 +205,13 @@ class DebugDrawHelper {
|
||||
});
|
||||
}
|
||||
|
||||
public function setDebugMode(debugMode: PhysicsWorld.DebugDrawMode) {
|
||||
this.debugMode = debugMode;
|
||||
public function setDebugMode(debugDrawMode: DebugDrawMode) {
|
||||
this.debugDrawMode = debugDrawMode;
|
||||
}
|
||||
|
||||
public function getDebugMode(): PhysicsWorld.DebugDrawMode {
|
||||
public function getDebugMode(): DebugDrawMode {
|
||||
#if js
|
||||
return debugMode;
|
||||
return debugDrawMode;
|
||||
#elseif hl
|
||||
return physicsWorld.getDebugDrawMode();
|
||||
#else
|
||||
@ -170,7 +220,7 @@ class DebugDrawHelper {
|
||||
}
|
||||
|
||||
function onRender(g: kha.graphics2.Graphics) {
|
||||
if (getDebugMode() == NoDebug && !physicsWorld.drawRaycasts) {
|
||||
if (getDebugMode() == NoDebug) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -179,7 +229,9 @@ class DebugDrawHelper {
|
||||
// will cause Bullet to call the btIDebugDraw callbacks), but this way
|
||||
// we can ensure that--within a frame--the function will not be called
|
||||
// before some user-specific physics update, which would result in a
|
||||
// one-frame drawing delay...
|
||||
// one-frame drawing delay... Ideally we would ensure that debugDrawWorld()
|
||||
// is called when all other (late) update callbacks are already executed...
|
||||
|
||||
physicsWorld.world.debugDrawWorld();
|
||||
|
||||
g.opacity = 1.0;
|
||||
@ -199,6 +251,17 @@ class DebugDrawHelper {
|
||||
}
|
||||
texts.resize(0);
|
||||
}
|
||||
|
||||
if (debugDrawMode & DrawRayCast != 0) {
|
||||
for (rayCastData in rayCasts) {
|
||||
if (rayCastData.hasHit) {
|
||||
drawRayCast(rayCastData.from, rayCastData.hitPoint, true);
|
||||
drawHitPoint(rayCastData.hitPoint);
|
||||
} else {
|
||||
drawRayCast(rayCastData.from, rayCastData.to, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,3 +304,14 @@ class TextData {
|
||||
public var color: kha.Color;
|
||||
public var text: String;
|
||||
}
|
||||
|
||||
@:structInit
|
||||
typedef TRayCastData = {
|
||||
var from: Vec4;
|
||||
var to: Vec4;
|
||||
var hasHit: Bool;
|
||||
@:optional var hitPoint: Vec4;
|
||||
@:optional var hitNormal: Vec4;
|
||||
}
|
||||
|
||||
#end
|
@ -71,7 +71,6 @@ class PhysicsWorld extends Trait {
|
||||
public var convexHitPointWorld = new Vec4();
|
||||
public var convexHitNormalWorld = new Vec4();
|
||||
var pairCache: Bool = false;
|
||||
public var drawRaycasts: Bool = false;
|
||||
|
||||
static var nullvec = true;
|
||||
static var vec1: bullet.Bt.Vector3 = null;
|
||||
@ -102,7 +101,7 @@ class PhysicsWorld extends Trait {
|
||||
|
||||
|
||||
|
||||
public function new(timeScale = 1.0, maxSteps = 10, solverIterations = 10, debugDrawMode: DebugDrawMode = NoDebug, drawRaycasts: Bool = false) {
|
||||
public function new(timeScale = 1.0, maxSteps = 10, solverIterations = 10, debugDrawMode: DebugDrawMode = NoDebug) {
|
||||
super();
|
||||
|
||||
if (nullvec) {
|
||||
@ -121,7 +120,6 @@ class PhysicsWorld extends Trait {
|
||||
this.timeScale = timeScale;
|
||||
this.maxSteps = maxSteps;
|
||||
this.solverIterations = solverIterations;
|
||||
this.drawRaycasts = drawRaycasts;
|
||||
|
||||
// First scene
|
||||
if (active == null) {
|
||||
@ -408,14 +406,6 @@ class PhysicsWorld extends Trait {
|
||||
var worldDyn: bullet.Bt.DynamicsWorld = world;
|
||||
var worldCol: bullet.Bt.CollisionWorld = worldDyn;
|
||||
|
||||
if (this.drawRaycasts && this.debugDrawHelper != null) {
|
||||
this.debugDrawHelper.drawRayCast(
|
||||
rayFrom.x(), rayFrom.y(), rayFrom.z(),
|
||||
rayTo.x(), rayTo.y(), rayTo.z(),
|
||||
0.73, 0.341, 1.0
|
||||
);
|
||||
}
|
||||
|
||||
worldCol.rayTest(rayFrom, rayTo, rayCallback);
|
||||
var rb: RigidBody = null;
|
||||
var hitInfo: Hit = null;
|
||||
@ -441,6 +431,16 @@ class PhysicsWorld extends Trait {
|
||||
#end
|
||||
}
|
||||
|
||||
if (getDebugDrawMode() & DrawRayCast != 0) {
|
||||
debugDrawHelper.rayCast({
|
||||
from: from,
|
||||
to: to,
|
||||
hasHit: rc.hasHit(),
|
||||
hitPoint: hitPointWorld,
|
||||
hitNormal: hitNormalWorld
|
||||
});
|
||||
}
|
||||
|
||||
#if js
|
||||
bullet.Bt.Ammo.destroy(rayCallback);
|
||||
#else
|
||||
@ -519,22 +519,14 @@ class PhysicsWorld extends Trait {
|
||||
|
||||
public function setDebugDrawMode(debugDrawMode: DebugDrawMode) {
|
||||
if (debugDrawHelper == null) {
|
||||
// Initialize if helper is null AND (standard debug mode is requested OR our custom raycast drawing is requested)
|
||||
if (debugDrawMode != NoDebug || this.drawRaycasts) {
|
||||
initDebugDrawing();
|
||||
}
|
||||
else {
|
||||
// Helper is null and no debug drawing needed, so exit
|
||||
if (debugDrawMode == NoDebug) {
|
||||
return;
|
||||
}
|
||||
initDebugDrawing(debugDrawMode);
|
||||
}
|
||||
|
||||
// If we reached here, the helper is initialized (or was already)
|
||||
// Now set the standard Bullet debug mode on the actual drawer
|
||||
#if js
|
||||
// Ensure drawer exists before setting mode (might have just been initialized)
|
||||
var drawer = world.getDebugDrawer();
|
||||
if (drawer != null) drawer.setDebugMode(debugDrawMode);
|
||||
world.getDebugDrawer().setDebugMode(debugDrawMode);
|
||||
#elseif hl
|
||||
hlDebugDrawer_setDebugMode(debugDrawMode);
|
||||
#end
|
||||
@ -554,8 +546,8 @@ class PhysicsWorld extends Trait {
|
||||
#end
|
||||
}
|
||||
|
||||
function initDebugDrawing() {
|
||||
debugDrawHelper = new DebugDrawHelper(this);
|
||||
function initDebugDrawing(debugDrawMode: DebugDrawMode) {
|
||||
debugDrawHelper = new DebugDrawHelper(this, debugDrawMode);
|
||||
|
||||
#if js
|
||||
final drawer = new bullet.Bt.DebugDrawer();
|
||||
@ -691,6 +683,8 @@ enum abstract DebugDrawMode(Int) from Int to Int {
|
||||
**/
|
||||
var DrawFrames = 1 << 15;
|
||||
|
||||
var DrawRayCast = 1 << 16;
|
||||
|
||||
@:op(~A) public inline function bitwiseNegate(): DebugDrawMode {
|
||||
return ~this;
|
||||
}
|
||||
|
Binary file not shown.
@ -324,6 +324,20 @@ class LeenkxExporter:
|
||||
def export_object_transform(self, bobject: bpy.types.Object, o):
|
||||
wrd = bpy.data.worlds['Lnx']
|
||||
|
||||
# HACK: In Blender 4.2.x, each camera must be selected to ensure its matrix is correctly assigned
|
||||
if bpy.app.version >= (4, 2, 0) and bobject.type == 'CAMERA' and bobject.users_scene:
|
||||
current_scene = bpy.context.window.scene
|
||||
|
||||
bpy.context.window.scene = bobject.users_scene[0]
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
bobject.select_set(True)
|
||||
bpy.context.view_layer.update()
|
||||
bobject.select_set(False)
|
||||
|
||||
bpy.context.window.scene = current_scene
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
# Static transform
|
||||
o['transform'] = {'values': LeenkxExporter.write_matrix(bobject.matrix_local)}
|
||||
|
||||
@ -1552,8 +1566,7 @@ class LeenkxExporter:
|
||||
log.error(e.message)
|
||||
else:
|
||||
# Assume it was caused because of encountering n-gons
|
||||
log.error(f"""object {bobject.name} contains n-gons in its mesh, so it's impossible to compute tanget space for normal mapping.
|
||||
Make sure the mesh only has tris/quads.""")
|
||||
log.error(f"""object {bobject.name} contains n-gons in its mesh, so it's impossible to compute tanget space for normal mapping. Make sure the mesh only has tris/quads.""")
|
||||
|
||||
tangdata = np.empty(num_verts * 3, dtype='<f4')
|
||||
if has_col:
|
||||
@ -3026,16 +3039,16 @@ Make sure the mesh only has tris/quads.""")
|
||||
if rbw is not None and rbw.enabled:
|
||||
out_trait['parameters'] = [str(rbw.time_scale), str(rbw.substeps_per_frame), str(rbw.solver_iterations)]
|
||||
|
||||
if phys_pkg == 'bullet':
|
||||
debug_draw_mode = 1 if wrd.lnx_bullet_dbg_draw_wireframe else 0
|
||||
debug_draw_mode |= 2 if wrd.lnx_bullet_dbg_draw_aabb else 0
|
||||
debug_draw_mode |= 8 if wrd.lnx_bullet_dbg_draw_contact_points else 0
|
||||
debug_draw_mode |= 2048 if wrd.lnx_bullet_dbg_draw_constraints else 0
|
||||
debug_draw_mode |= 4096 if wrd.lnx_bullet_dbg_draw_constraint_limits else 0
|
||||
debug_draw_mode |= 16384 if wrd.lnx_bullet_dbg_draw_normals else 0
|
||||
debug_draw_mode |= 32768 if wrd.lnx_bullet_dbg_draw_axis_gizmo else 0
|
||||
if phys_pkg == 'bullet' or phys_pkg == 'oimo':
|
||||
debug_draw_mode = 1 if wrd.lnx_physics_dbg_draw_wireframe else 0
|
||||
debug_draw_mode |= 2 if wrd.lnx_physics_dbg_draw_aabb else 0
|
||||
debug_draw_mode |= 8 if wrd.lnx_physics_dbg_draw_contact_points else 0
|
||||
debug_draw_mode |= 2048 if wrd.lnx_physics_dbg_draw_constraints else 0
|
||||
debug_draw_mode |= 4096 if wrd.lnx_physics_dbg_draw_constraint_limits else 0
|
||||
debug_draw_mode |= 16384 if wrd.lnx_physics_dbg_draw_normals else 0
|
||||
debug_draw_mode |= 32768 if wrd.lnx_physics_dbg_draw_axis_gizmo else 0
|
||||
debug_draw_mode |= 65536 if wrd.lnx_physics_dbg_draw_raycast else 0
|
||||
out_trait['parameters'].append(str(debug_draw_mode))
|
||||
out_trait['parameters'].append(str(wrd.lnx_bullet_dbg_draw_raycast).lower())
|
||||
|
||||
self.output['traits'].append(out_trait)
|
||||
|
||||
|
13
leenkx/blender/lnx/logicnode/array/LN_array_index_list.py
Normal file
13
leenkx/blender/lnx/logicnode/array/LN_array_index_list.py
Normal file
@ -0,0 +1,13 @@
|
||||
from lnx.logicnode.lnx_nodes import *
|
||||
|
||||
class ArrayIndexNode(LnxLogicTreeNode):
|
||||
"""Returns the array index list of the given value as an array."""
|
||||
bl_idname = 'LNArrayIndexListNode'
|
||||
bl_label = 'Array Index List'
|
||||
lnx_version = 1
|
||||
|
||||
def lnx_init(self, context):
|
||||
self.add_input('LnxNodeSocketArray', 'Array')
|
||||
self.add_input('LnxDynamicSocket', 'Value')
|
||||
|
||||
self.add_output('LnxNodeSocketArray', 'Array')
|
@ -170,32 +170,64 @@ vec3 random3(const vec3 c) {
|
||||
r.y = fract(512.0 * j);
|
||||
return r - 0.5;
|
||||
}
|
||||
float tex_musgrave_f(const vec3 p) {
|
||||
|
||||
float noise_tex(const vec3 p) {
|
||||
const float F3 = 0.3333333;
|
||||
const float G3 = 0.1666667;
|
||||
|
||||
vec3 s = floor(p + dot(p, vec3(F3)));
|
||||
vec3 x = p - s + dot(s, vec3(G3));
|
||||
vec3 e = step(vec3(0.0), x - x.yzx);
|
||||
vec3 i1 = e*(1.0 - e.zxy);
|
||||
vec3 i2 = 1.0 - e.zxy*(1.0 - e);
|
||||
vec3 i1 = e * (1.0 - e.zxy);
|
||||
vec3 i2 = 1.0 - e.zxy * (1.0 - e);
|
||||
|
||||
vec3 x1 = x - i1 + G3;
|
||||
vec3 x2 = x - i2 + 2.0*G3;
|
||||
vec3 x3 = x - 1.0 + 3.0*G3;
|
||||
vec4 w, d;
|
||||
w.x = dot(x, x);
|
||||
w.y = dot(x1, x1);
|
||||
w.z = dot(x2, x2);
|
||||
w.w = dot(x3, x3);
|
||||
w = max(0.6 - w, 0.0);
|
||||
vec3 x2 = x - i2 + 2.0 * G3;
|
||||
vec3 x3 = x - 1.0 + 3.0 * G3;
|
||||
|
||||
vec4 w;
|
||||
w.x = max(0.6 - dot(x, x), 0.0);
|
||||
w.y = max(0.6 - dot(x1, x1), 0.0);
|
||||
w.z = max(0.6 - dot(x2, x2), 0.0);
|
||||
w.w = max(0.6 - dot(x3, x3), 0.0);
|
||||
|
||||
w = w * w;
|
||||
w = w * w;
|
||||
|
||||
vec4 d;
|
||||
d.x = dot(random3(s), x);
|
||||
d.y = dot(random3(s + i1), x1);
|
||||
d.z = dot(random3(s + i2), x2);
|
||||
d.w = dot(random3(s + 1.0), x3);
|
||||
w *= w;
|
||||
w *= w;
|
||||
|
||||
d *= w;
|
||||
return clamp(dot(d, vec4(52.0)), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float tex_musgrave_f(const vec3 p, float detail, float distortion) {
|
||||
// Apply distortion to the input coordinates smoothly with noise_tex
|
||||
vec3 distorted_p = p + distortion * vec3(
|
||||
noise_tex(p + vec3(5.2, 1.3, 7.1)),
|
||||
noise_tex(p + vec3(1.7, 9.2, 3.8)),
|
||||
noise_tex(p + vec3(8.3, 2.8, 4.5))
|
||||
);
|
||||
|
||||
float value = 0.0;
|
||||
float amplitude = 1.0;
|
||||
float frequency = 1.0;
|
||||
|
||||
// Use 'detail' as number of octaves, clamped between 1 and 8
|
||||
int octaves = int(clamp(detail, 1.0, 8.0));
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
value += amplitude * noise_tex(distorted_p * frequency);
|
||||
frequency *= 2.0;
|
||||
amplitude *= 0.5;
|
||||
}
|
||||
|
||||
return clamp(value, 0.0, 1.0);
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
# col: the incoming color
|
||||
|
@ -254,10 +254,10 @@ if bpy.app.version < (4, 1, 0):
|
||||
co = 'bposition'
|
||||
|
||||
scale = c.parse_value_input(node.inputs['Scale'])
|
||||
# detail = c.parse_value_input(node.inputs[2])
|
||||
# distortion = c.parse_value_input(node.inputs[3])
|
||||
|
||||
res = f'tex_musgrave_f({co} * {scale} * 0.5)'
|
||||
detail = c.parse_value_input(node.inputs[3])
|
||||
distortion = c.parse_value_input(node.inputs[4])
|
||||
|
||||
res = f'tex_musgrave_f({co} * {scale} * 0.5, {detail}, {distortion})'
|
||||
|
||||
return res
|
||||
|
||||
@ -278,11 +278,11 @@ def parse_tex_noise(node: bpy.types.ShaderNodeTexNoise, out_socket: bpy.types.No
|
||||
distortion = c.parse_value_input(node.inputs[5])
|
||||
if bpy.app.version >= (4, 1, 0):
|
||||
if node.noise_type == "FBM":
|
||||
state.curshader.add_function(c_functions.str_tex_musgrave)
|
||||
if out_socket == node.outputs[1]:
|
||||
state.curshader.add_function(c_functions.str_tex_musgrave)
|
||||
res = 'vec3(tex_musgrave_f({0} * {1}), tex_musgrave_f({0} * {1} + 120.0), tex_musgrave_f({0} * {1} + 168.0))'.format(co, scale, detail, distortion)
|
||||
res = 'vec3(tex_musgrave_f({0} * {1}, {2}, {3}), tex_musgrave_f({0} * {1} + 120.0, {2}, {3}), tex_musgrave_f({0} * {1} + 168.0, {2}, {3}))'.format(co, scale, detail, distortion)
|
||||
else:
|
||||
res = f'tex_musgrave_f({co} * {scale} * 1.0)'
|
||||
res = f'tex_musgrave_f({co} * {scale} * 1.0, {detail}, {distortion})'
|
||||
else:
|
||||
if out_socket == node.outputs[1]:
|
||||
res = 'vec3(tex_noise({0} * {1},{2},{3}), tex_noise({0} * {1} + 120.0,{2},{3}), tex_noise({0} * {1} + 168.0,{2},{3}))'.format(co, scale, detail, distortion)
|
||||
|
@ -86,7 +86,7 @@ def write(vert, particle_info=None, shadowmap=False):
|
||||
vert.write('p_fade = sin(min((p_age / 2) * 3.141592, 3.141592));')
|
||||
|
||||
if out_index:
|
||||
vert.add_out('float p_index');
|
||||
vert.add_out('float p_index')
|
||||
vert.write('p_index = gl_InstanceID;')
|
||||
|
||||
def write_tilesheet(vert):
|
||||
|
@ -209,7 +209,8 @@ def make_instancing_and_skinning(mat: Material, mat_users: Dict[Material, List[O
|
||||
global_elems.append({'name': 'ipos', 'data': 'float3'})
|
||||
if 'Rot' in inst:
|
||||
global_elems.append({'name': 'irot', 'data': 'float3'})
|
||||
if 'Scale' in inst:
|
||||
#HACK: checking `mat.arm_particle_flag` to force appending 'iscl' to the particle's vertex shader
|
||||
if 'Scale' in inst or mat.arm_particle_flag:
|
||||
global_elems.append({'name': 'iscl', 'data': 'float3'})
|
||||
|
||||
elif inst == 'Off':
|
||||
|
@ -77,6 +77,25 @@ class LNX_MT_NodeAddOverride(bpy.types.Menu):
|
||||
layout.separator()
|
||||
layout.menu(f'LNX_MT_{INTERNAL_GROUPS_MENU_ID}_menu', text=internal_groups_menu_class.bl_label, icon='OUTLINER_OB_GROUP_INSTANCE')
|
||||
|
||||
elif context.space_data.tree_type == 'ShaderNodeTree':
|
||||
# TO DO - Recursively gather nodes and draw them to menu
|
||||
|
||||
LNX_MT_NodeAddOverride.overridden_draw(self, context)
|
||||
|
||||
layout = self.layout
|
||||
layout.separator()
|
||||
layout.separator()
|
||||
col = layout.column()
|
||||
col.label(text="Custom")
|
||||
|
||||
shader_data_op = col.operator("node.add_node", text="Shader Data")
|
||||
shader_data_op.type = "LnxShaderDataNode"
|
||||
shader_data_op.use_transform = True
|
||||
|
||||
particle_op = col.operator("node.add_node", text="Custom Particle")
|
||||
particle_op.type = "LnxCustomParticleNode"
|
||||
particle_op.use_transform = True
|
||||
|
||||
else:
|
||||
LNX_MT_NodeAddOverride.overridden_draw(self, context)
|
||||
|
||||
|
@ -197,38 +197,38 @@ def init_properties():
|
||||
items=[('Bullet', 'Bullet', 'Bullet'),
|
||||
('Oimo', 'Oimo', 'Oimo')],
|
||||
name="Physics Engine", default='Bullet', update=assets.invalidate_compiler_cache)
|
||||
bpy.types.World.lnx_bullet_dbg_draw_wireframe = BoolProperty(
|
||||
bpy.types.World.lnx_physics_dbg_draw_wireframe = BoolProperty(
|
||||
name="Collider Wireframes", default=False,
|
||||
description="Draw wireframes of the physics collider meshes and suspensions of raycast vehicle simulations"
|
||||
)
|
||||
bpy.types.World.lnx_bullet_dbg_draw_raycast = BoolProperty(
|
||||
name="Trace Raycast", default=False,
|
||||
bpy.types.World.lnx_physics_dbg_draw_raycast = BoolProperty(
|
||||
name="Raycasts", default=False,
|
||||
description="Draw raycasts to trace the results"
|
||||
)
|
||||
bpy.types.World.lnx_bullet_dbg_draw_aabb = BoolProperty(
|
||||
bpy.types.World.lnx_physics_dbg_draw_aabb = BoolProperty(
|
||||
name="Axis-aligned Minimum Bounding Boxes", default=False,
|
||||
description="Draw axis-aligned minimum bounding boxes (AABBs) of the physics collider meshes"
|
||||
)
|
||||
bpy.types.World.lnx_bullet_dbg_draw_contact_points = BoolProperty(
|
||||
bpy.types.World.lnx_physics_dbg_draw_contact_points = BoolProperty(
|
||||
name="Contact Points", default=False,
|
||||
description="Visualize contact points of multiple colliders"
|
||||
)
|
||||
bpy.types.World.lnx_bullet_dbg_draw_constraints = BoolProperty(
|
||||
bpy.types.World.lnx_physics_dbg_draw_constraints = BoolProperty(
|
||||
name="Constraints", default=False,
|
||||
description="Draw axis gizmos for important constraint points"
|
||||
)
|
||||
bpy.types.World.lnx_bullet_dbg_draw_constraint_limits = BoolProperty(
|
||||
bpy.types.World.lnx_physics_dbg_draw_constraint_limits = BoolProperty(
|
||||
name="Constraint Limits", default=False,
|
||||
description="Draw additional constraint information such as distance or angle limits"
|
||||
)
|
||||
bpy.types.World.lnx_bullet_dbg_draw_normals = BoolProperty(
|
||||
bpy.types.World.lnx_physics_dbg_draw_normals = BoolProperty(
|
||||
name="Face Normals", default=False,
|
||||
description=(
|
||||
"Draw the normal vectors of the triangles of the physics collider meshes."
|
||||
" This only works for mesh collision shapes"
|
||||
" This only works with Bullet physics, for mesh collision shapes"
|
||||
)
|
||||
)
|
||||
bpy.types.World.lnx_bullet_dbg_draw_axis_gizmo = BoolProperty(
|
||||
bpy.types.World.lnx_physics_dbg_draw_axis_gizmo = BoolProperty(
|
||||
name="Axis Gizmos", default=False,
|
||||
description=(
|
||||
"Draw a small axis gizmo at the origin of the collision shape."
|
||||
|
@ -1907,7 +1907,7 @@ class LNX_PT_RenderPathPostProcessPanel(bpy.types.Panel):
|
||||
col.prop(rpdat, "rp_bloom")
|
||||
_col = col.column()
|
||||
_col.enabled = rpdat.rp_bloom
|
||||
if bpy.app.version <= (4, 2, 4):
|
||||
if bpy.app.version < (4, 3, 0):
|
||||
_col.prop(rpdat, 'lnx_bloom_follow_blender')
|
||||
if not rpdat.lnx_bloom_follow_blender:
|
||||
_col.prop(rpdat, 'lnx_bloom_threshold')
|
||||
@ -2749,20 +2749,20 @@ class LNX_PT_BulletDebugDrawingPanel(bpy.types.Panel):
|
||||
layout.use_property_decorate = False
|
||||
wrd = bpy.data.worlds['Lnx']
|
||||
|
||||
if wrd.lnx_physics_engine != 'Bullet':
|
||||
if wrd.lnx_physics_engine != 'Bullet' and wrd.lnx_physics_engine != 'Oimo':
|
||||
row = layout.row()
|
||||
row.alert = True
|
||||
row.label(text="Physics debug drawing is only supported for the Bullet physics engine")
|
||||
row.label(text="Physics debug drawing is only supported for the Bullet and Oimo physics engines")
|
||||
|
||||
col = layout.column(align=False)
|
||||
col.prop(wrd, "lnx_bullet_dbg_draw_wireframe")
|
||||
col.prop(wrd, "lnx_bullet_dbg_draw_raycast")
|
||||
col.prop(wrd, "lnx_bullet_dbg_draw_aabb")
|
||||
col.prop(wrd, "lnx_bullet_dbg_draw_contact_points")
|
||||
col.prop(wrd, "lnx_bullet_dbg_draw_constraints")
|
||||
col.prop(wrd, "lnx_bullet_dbg_draw_constraint_limits")
|
||||
col.prop(wrd, "lnx_bullet_dbg_draw_normals")
|
||||
col.prop(wrd, "lnx_bullet_dbg_draw_axis_gizmo")
|
||||
col.prop(wrd, "lnx_physics_dbg_draw_wireframe")
|
||||
col.prop(wrd, "lnx_physics_dbg_draw_raycast")
|
||||
col.prop(wrd, "lnx_physics_dbg_draw_aabb")
|
||||
col.prop(wrd, "lnx_physics_dbg_draw_contact_points")
|
||||
col.prop(wrd, "lnx_physics_dbg_draw_constraints")
|
||||
col.prop(wrd, "lnx_physics_dbg_draw_constraint_limits")
|
||||
col.prop(wrd, "lnx_physics_dbg_draw_normals")
|
||||
col.prop(wrd, "lnx_physics_dbg_draw_axis_gizmo")
|
||||
|
||||
def draw_custom_node_menu(self, context):
|
||||
"""Extension of the node context menu.
|
||||
|
@ -828,8 +828,8 @@ def check_blender_version(op: bpy.types.Operator):
|
||||
"""Check whether the Blender version is supported by Leenkx,
|
||||
if not, report in UI.
|
||||
"""
|
||||
if bpy.app.version[0] != 4 or bpy.app.version[1] != 2:
|
||||
op.report({'INFO'}, 'INFO: For Leenkx to work correctly, use a Blender LTS version such as 4.2 | 3.6 | 3.3')
|
||||
if bpy.app.version[:2] not in [(4, 4), (4, 2), (3, 6), (3, 3)]:
|
||||
op.report({'INFO'}, 'INFO: For Leenkx to work correctly, use a Blender LTS version')
|
||||
|
||||
|
||||
def check_saved(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user