Truespace Script Custom Event

OnCustomEvent

For some special situations you may need to define custom communication between your objects.
Use RsApp.SendCustomEvent method to send an event and implement OnCustomEvent to handle the
event.

function OnCustomEvent(params)
{
	var eventData = params.Param('vtEventData');
	System.Trace(eventData)
}
RsApp.SendCustomEvent(Space.CurrentScene() + "/target", "hello")

It should be possible to send an event to one object and have it relay to all items in a scene making interface type behaviors – todo test this theory

Random Truespace Dev Notes

   BFMT_UNKNOWN    = 0;
   BFMT_A8R8G8B8    = 1;
   BFMT_A16B16G16R16    = 2;
   BFMT_A32fB32fG32fR32f    = 3;
   BFMT_R8    = 4;
   BFMT_R16    = 5;
   BFMT_R32f    = 6;
   BFMT_FORCE_DWORD    = -1;

bitmap format R8 may be invalid for exported images

popup panel – can get a panel frame by dragging an item out of the panel stack view. Set the RootNode connector value to the parent of the object that will be displayed. Set the Panel Node connector of the Panel Node to the node that will be floating. Copy into Windows Manager Space and run 2 mystery commands then set the panel aspect.

	WindowsManager.CloseWindow("Project/Windows Manager Space/TestPanelFrame")
	var rpf = Space.CurrentScene() + "/TestPanelFrame";

	Node.Value(rpf, "RootNode") = Space.CurrentScene();
	Node.Value(rpf + "/Panel Node", "PanelEditorNode") = Space.CurrentScene() + "/YafaRay IES Spot";
	Node.Copy(rpf, "/Project/Windows Manager Space");
	WindowsManager.Activate();
	WindowsManager.UpdateWindowsStructure();
	//UserInterface.SetAspect(Space.CurrentScene() + "/YafaRay IES Spot", 0);//icon
	//UserInterface.SetAspect(Space.CurrentScene() + "/YafaRay IES Spot", 1);//???
	//UserInterface.SetAspect(Space.CurrentScene() + "/YafaRay IES Spot", 2);//Exp
	//UserInterface.SetAspect(Space.CurrentScene() + "/YafaRay IES Spot", 3);//Default
	UserInterface.SetAspect(Space.CurrentScene() + "/YafaRay IES Spot", 4);//color

some file notes – appending writes to the end of a file. TristateTrue will write utf-8 files compatible with the xml files in trueSpace.

	var filename = params.ConValue('filename');
	var forReading = 1, forWriting = 2, forAppending = 8;
	var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0;
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	var connToFile = file.OpenAsTextStream( forReading , TristateUseDefault);
var curLine = connToFile.ReadLine();
connToFile.Close();
fso.FileExists
fso.CopyFile(System.GetMainDir() + "\\Scripts\\reset.js", System.GetMainDir() + "\\Scripts\\resetORIGINAL.js", true);
	var f = fso.GetFile(System.GetMainDir() + "\\Scripts\\reset.js");
	var connToFile = f.OpenAsTextStream( forReading, TristateUseDefault );
	var filecontents = connToFile.ReadAll();
	connToFile.Close();
connToFile.WriteLine
fso.CopyFolder(YafaRay4tSv090 + '\\YafaRay4tS Setup', tS + 'Rs Main Libraries\\', true)
fso.DeleteFile

sample write utf8 xml file

function WriteRenderPath(renderLibrary)
{
	var forReading = 1, forWriting = 2, forAppending = 8;
	var TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0; 

	var fso = new ActiveXObject("Scripting.FileSystemObject");

	var f = fso.GetFile(System.GetMainDir() + "\\Scripts\\D3DView.RenderToFile.Settings.xml");

	if(!f) {
		System.Alert("d3dview render to file xml not found.");
		return;
	}

	lines = [];

	connToFile = f.OpenAsTextStream( forReading, TristateTrue );//unicode

	while (!connToFile.AtEndOfStream) {

		lines.push(connToFile.ReadLine());
	}

	connToFile.Close();

	connToFile = f.OpenAsTextStream( forWriting, TristateTrue );//unicode

	re = /FILENAME="[\w|\:|\\|\.|\s]+"/;

	for(var i=0;i<lines.length;i++) {
		curline = lines[i];
		//System.Trace(curline);
		matchArray = curline.match(re);

		if(matchArray) {
			var currentRenderFile = matchArray[0].split('"')[1];
			var basename = fso.GetBaseName(currentRenderFile);
			var ext = fso.GetExtensionName(currentRenderFile);
			curline = curline.replace(re,'FILENAME="' + renderLibrary + '\\' + basename + '.' + ext + '"')
			//System.Trace(curline);
		}
		connToFile.WriteLine(curline);
	}
	connToFile.Close();
}
RsFileIO.SaveObject(tS + '\\Scripts\\preobjects\\Yafaray Folder.rsobj', System.ThisOwner() + "/Yafaray Folder")
RsFileIO.LoadObject(tS + '\\Rs Main Libraries\\YafaRay4tS Setup\\YafaRay Camera.RsObj', "/Preferences/Cameras")
always close a window not delete it
WindowsManager.CloseWindow("/Project/Windows Manager Space/YafaRay Toolbar Frame")
after copy to windows manager space
		WindowsManager.Activate()
		WindowsManager.UpdateWindowsStructure()
open view in panel stack – 6 is the aspect
UserInterface.OpenToolPanelViewEx2("", "", Space.CurrentScene() + "/YafaRay4tS", 6, 1, 0);
Activity.Run
ScriptObject.Execute

keyframe range

keyframe range
	//RsTime.EvalAnimStart and RsTime.EvalAnimEnd seem to ignore all arguments
	// and only operate on the entire scene animation

//alters the play range anim pref values"
		try {
			animStart = RsTime.EvalAnimStart('');
			animEnd = RsTime.EvalAnimEnd('');
play range
	var playRangeStart = RsAnimPref.PlayRangeStart;
	var playRangeEnd = RsAnimPref.PlayRangeEnd;

timeline range
Node.Value("%THIS_NAME%" , "Start_Frame") = Node.Value("AnimMng", "AnimStart");
Node.Value("%THIS_NAME%", "Number_Start") = Node.Value("AnimMng", "AnimStart");
Node.Value("%THIS_NAME%", "End_Frame") = Node.Value("AnimMng", "AnimEnd");
status line
	if(Node.Exists("/Status Line")) {
		if(!Node.ConExists("Status Line", "Model"))
			Node.ConCreate("Status Line", "Model", "string", 4);
		Node.Value("/Status Line","Model") = "Rendering...";
	}
folder enumeration and reg exp matching
var folder = fso.GetFolder(tspath); 
	var folderEnum = new Enumerator(folder.SubFolders); 
 
	var regexp = /YafaRay/i

	for(;!folderEnum.atEnd(); folderEnum.moveNext()) {
		var cur = folderEnum.item();
		var curArray = (cur+"").split("\\");
		var s = "" + curArray[curArray.length-1];
		if(s.match(regexp)) {
			temppath = fso.BuildPath(cur,"bin");
			temppath = fso.BuildPath(temppath,"yafaray-xml.exe");
			if(fso.FileExists(temppath)) {
				yafpath = temppath;
				break;
			}
		}
	}
temp path
	var WshShell = new ActiveXObject("WScript.Shell");
    
	WshSysEnv = WshShell.Environment("PROCESS");
	temppath = WshSysEnv("TEMP");
time stamp
var theDate = new Date();
	var y = theDate.getYear();
	var mo = theDate.getMonth() + 1;
	var d = theDate.getDate();
	var h = theDate.getHours();
	var mi = theDate.getMinutes();
	var s = theDate.getSeconds();

	if(mo < 10) mo = "0" + mo;
	if(d < 10) d = "0" + d;
	if(h < 10) h = "0" + h;
	if(mi < 10) mi = "0" + mi;
	if(s < 10) s = "0" + s;

	var timestamp = "_" + y + mo + d + h + mi + s;
string enum
var recentPlaces = System.CreateDO("Common Data Package/String Enum Data");

	//try catch only way to check for uninitialized value
	try {
		recentPlaces = Node.Value(owner, "RecentPlaces");
	} catch(e) {
		recentPlaces.Clear();
		Node.Value(owner, "RecentPlaces") = recentPlaces;
	}

	if(recentPlaces.GetSize() == 0) return;

	thedata = recentPlaces.GetSelectedString();

	var newRecentPlaces = System.CreateDO("Common Data Package/String Enum Data");

	newRecentPlaces.SetStringAt(0,libraryPlace);
get frame rate
frameRateEnum = System.CreateDO('Common Data Package/String Enum Data');
	
	frameRateEnum = Node.Value("Preferences/AnimPref","Frame Rate");

	frameRateString = frameRateEnum.GetSelectedString();

	frameRate = 30;
	if(frameRateString=="15 fps")
		frameRate = 15;
	if(frameRateString=="Film 24 fps")
		frameRate = 24;
	if(frameRateString=="PAL 25 fps")
		frameRate = 25;
	if(frameRateString=="30 fps")
		frameRate = 30;
	if(frameRateString=="60 fps")
		frameRate = 60;
sel = Node.Selection(); //list of selected nodes
	numsel = Node.SelectionLength(sel); // number of selected nodes
	theParent = Node.SelectionGetAt(sel, numsel-1); //last selected item will be the parent
	var mybitmap = System.CreateDO("Common Data Package/Bitmap Data");

	BFMT_A8R8G8B8	= 1;

	mybitmap.Create(256,256,BFMT_A8R8G8B8);
	var color = System.CreateDO('Common Data Package/Color Data');
			color.SetColor(val,val,val,1);
			mybitmap.SetPixel(x+126,y+126,color);
if(!DebugViewFound("Project/Windows Manager Space"))
        CmdPrompt.DebugView('Windows Manager Space', 0);
}

function NodeSubObject(root, index)
{
    return root + "/" + Node.SubObject(root, index);
}

function DebugViewFound()
{
    var WMS = "Project/Windows Manager Space";
    var numwindows = Node.SubObjectCount(WMS);

    for(var winIndex=0; winIndex < numwindows; winIndex++)
    {
        var currentWindow = NodeSubObject(WMS, winIndex);
        if(Node.SubObjectCount(currentWindow) < 1)
            continue;

        var shortname = Node.ShortName(NodeSubObject(currentWindow, 0));
        if( shortname == "LogOutput")
            return true;
    }
    return false;
}

Widgets.Rotate == rotate about origin (0,0,0) then offset back to original position

Node.Selection() – returns a selection list with a semicolon delimination, but has leading spaces in each nodes path so needs to be adjusted to work with Space.Select

sel = Node.Selection();
selArray = sel.split(";");
re = /^\s/; // whitespace in first character position
sel = selArray[0].replace(re,"");
if(selArray.length > 1)
        for(i=1;i<selArray.length;i++)
                sel = sel + ";" + selArray[i].replace(re,"");

Node.Select – select one node

Space.Unselect()

%THIS_OWNER_NAME%

LE. – (L E dot) undocumented LE commands

Activity.Run(scene + “/second”);//runs after the calling script is done

ScriptObject.Execute(scene + “/second”);//runs immediately pausing the calling script

If you add a new connector to a script used inside the Widgets it won’t work right away. Restarting truespace will unstick it.

//functions for generating random guid for marker display
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function guid() {
return (“{“ + S4()+S4()+“-“+S4()+“-“+S4()+“-“+S4()+“-“+S4()+S4()+S4() + “}”);
}
WshShell = new ActiveXObject(“WScript.Shell”);
WshShell.Run(“calc”);

matrix multiplication

   myMatrix.LoadIdentity();
   myMatrix.SetPitch(-90);// myMatrix = -90 deg pitch => last rotation
   myMatrix.Mult(rollMatrix);// rollMatrix (this is the second rotation) * myMatrix => myMatrix
   myMatrix.Mult(yawMatrix);// yawMatrix (this is the first rotation) * myMatrix => myMatrix
   final result in myMatrix is yaw then roll then pitch
Local matrix from world matrices
theMatrix = Node.Value(bindgroup + "/" + subNode, "WldMatrix");
parentMatrix = Node.Value(bindParent, "WldMatrix");
parInvert = parentMatrix.Invert();
theMatrix.Mult(parInvert);
//now theMatrix contains local instead of world

Space.Select() – select multiple nodes from text string separated by semi colons, node paths in the list must not have leading spaces

sel = Node.Selection();
selArray = sel.split(";");
re = /^\s/; // whitespace in first character position
sel = selArray[0].replace(re,"");
if(selArray.length > 1)
        for(i=1;i<selArray.length;i++)
                sel = sel + ";" + selArray[i].replace(re,"");
Node.Select – select one node
Space.Unselect()
	var strEnum = System.CreateDO("Common Data Package/String Enum Data");
	try {
		strEnum = Node.Value("/Offline renderers", "Renderer");
	} catch(e) {
		strEnum.Clear();
	}
	var selString = strEnum.GetSelectedString();
	System.Alert(selString);

Node.Selection() – returns a selection list with a semicolon delimination, but has leading spaces in each nodes path so needs to be adjusted to work with Space.Select