Truespace Script Buffer

trueSpace scripts create an undo step for each command in the script that changes the graph. So a single script can have many undo steps generated. The trueSpace script buffer will run a collection of script commands in the form of a string and generate only 1 undo.

Untested idea, pass complex data structures to the buffer using a function set.

var cmd = ''
// note that if System.ThisOwner() is included in the buffer tS will crash
var thisowner = System.ThisOwner()
cmd += var owner = "' + thisowner + '";'
cmd += 'System.Trace(owner)'
RsApp.RunScriptBuffer(cmd);

trueSpace Delete Bug

When selected items are deleted the Node commands still behave as if the selection exists. Code below shows how to check for a valid selection before using it.

// Execute 
// Called to execute the command 
function Execute(params)
{
    if(!IsValidSelection(Node.Selection())) return;
    System.Trace("selection is good");
}
function IsValidSelection(selection)
{
    if(!selection) return false;
    var reWhiteSpace = /^\s/; // whitespace in first character
    var selectionArray = selection.split(";");
    for(var i = 0; i < selectionArray.length; i++) {
        var selClean = selectionArray[i].replace(reWhiteSpace, "");
        if(!Node.Exists(selClean)) {
            return false;
        }
    }
    return true;
}

trueSpace script params

function Execute(params)
{
	var controlIn1 = params.ConValue('controlIn1');
	var controlIn2 = params.ConValue('controlIn2');

	var scriptFrom = params.GetControlIn();

	System.Trace(scriptFrom);

	if(scriptFrom == "controlIn2")
		params.SetControlOut("ControlOut2")
	else
		params.SetControlOut("ControlOut1")

	// params.ConValue("controlOut1") = ...
	// params.ConValue("ControlOut2") = ...
}

params.GetControlIn() gets the name of the control input that runs the script, so can have several input controls and make code decisions based on which input was used
params.SetControlOut(str) does the opposite and lets you choose which output control will fire off

params.SetTerminationFlag() will stop all downstream execution

params.GetControlIn() does not work, so this whole idea is dead

Random trueSpace Notes

The script command Physics.Impulse has max XYZ values of 100. Higher values are ignored. This command only has a small effect on the object motion.

When working with script combined with the axis tool always flatten the axis back into the geometry.

The saturate node for materials does not load into trueSpace. It just gives an error.

RsApp.Help() command needs the xslt file found in the home directory in order to view the resulting xml files properly.

IK locks and IK handles attach to bones, not to joints.

A jscript object cannot properly read changes to a universal array connector if was changed from outside by a command script.

The params object can be used to stop down stream execution of command scripts via params.SetTerminationFlag()

When editing a morph target it seems best to set mesh editor auto triangulation setting to “None” .

Linear interpolation works best for IK skeletons to prevent sliding.

Creating Plugins with Unreal4 – 3DBuzz lesson notes

Updated notes for UE4 v4.23.0, Creating Plugins with Unreal4 videos

https://www.3dbuzz.com/forum/threads/204335-Creating-Plugins-with-Unreal-4-some-notes-for-version-4-10-1?p=1616145#post1616145

video 03

don’t create file folder structure, instead
Edit > Plugins > New Plugin
blank template …

edit CoolPlugin.uplugin and change “RunTime” to “Editor”

edit CoolPlugin.Build.cs and add private dependencies
“UnrealEd”,
“InputCore”,
“Core”,
“EditorStyle”,
“CoreUObject”

Use the files created by the New Plugins process, CoolPlugin.h and CoolPlugin.cpp instead of Module.cpp and Module.h
Skip creation of PCH file? – looks like something is built in already?

video 04

Edit > Editor Preferences, General > Miscellaneous, check Display UI Extension Points – shows that “WindowLocalTabSpawners” does not exist, so use “WindowGlobalTabSpawners” instead

replace #include “Slate.h” with

include “SlateBasics.h”

include “SlateExtras.h”

LOCTEXT_NAMESPACE already exists from the New Plugins process

change all references from “Module” to “FCoolPluginModule”

place new code inside the LOCTEXT_NAMESPACE define

video 05

place CoolWindow.h before CoolPlugin.h inside the CoolWindow.cpp file

video 06 – nothing

video 07


first error is for ATriggerBox – search unreal online docs for ATriggerBox – api says #include “Engine/TriggerBox.h”
add #include “Engine/TriggerBox.h” to the CoolPlugin.h file

error – cannot convert from FString to FText
CoolWindow.h change FString GetBoundsActorName() to FText GetBoundsActorName()
CoolWindow.cpp the same change and wrap the return values with FText::FromString(xxx)

error – iterator wont work, undefined class TActorIterator, ATriggerBox already has include so should be ok
search docs for TActorIterator says #include “EngineUtils.h”
add #include “EngineUtils.h” to the CoolPlugin.h file

error – cannot convert TIndirectArray to TArray
hover on GEngine->GetWorldContexts() shows that it returns a TIndirectArray not an TArray – so change TArray to TIndirectArray

video 08


convert FString to FText error for GetAlleySpaceText, wrap return value with FText::FromString(xxx)

video 09


error – UCubeBuilder not defined, search docs shows UBrushBuilder, with a link to UEditorBrushBuilder and now can see a UCubeBuilder link, finally UCubeBuilder says #include “Builders/CubeBuilder.h”
add #include “Builders/CubeBuilder.h” to the CoolPlugin.h file

error – GetBrush is not member of UWorld, so replace GetBrush with GetDefaultBrush

strange FText conversion error const Othertype to FText::EInitToEmptyString, error from file Attribute.h
output console error points to the .Text(FString(TEXT(“Build”)))
replace with .Text(LOCTEXT(“Build”,”Build”))

and now the whole thing works with ue 4.23.0

Question Messagebox

The trueSpace scripting question messagebox can be hidden behind the main display. This is a solution to that problem.

// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox
function Question(strText)
{
	var nSecondsToWait = -1;
	var strTitle = "Question";
	// values are hexadecimal
	var MB_YESNO = 4;
	var MB_SYSTEMMODAL = 4096;//1000L force on top
	var MB_ICONQUESTION = 32;//20L question mark symbol

	var nType = MB_YESNO+MB_SYSTEMMODAL+MB_ICONQUESTION;
	var IDYES = 6;
	var IDNO = 7;

	var shell = new ActiveXObject("WScript.shell");
	var button = shell.Popup (strText, nSecondsToWait, strTitle, nType);

	if(button == IDYES) return true;
	return false;
}

if(!Question("Special mesh processing\nDo you wish to continue?")) {
params.ConValue("abort") = 1;
return;
}

Misc trueSpace script

// https://rosettacode.org/wiki/Map_range
function MapRange(val,a1,a2,b1,b2)
{
	var val2 = Math.min(val,a2);
	s = Math.max(val2, a1);
	return b1 + (s-a1)*(b2-b1)/(a2-a1)
}

map range a1,a2 to b1,b2

RsAnim.PutFrame places a single item at a certain frame without affecting other items in the scene, useful for some “set driven key” type behaviors.