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

Cardboard (GoogleVR) Quickstart for UE4

These are my notes for an alternate Quick Start Guide for Google Cardboard using Unreal Engine 4. I’m using a custom viewer made for the Nexus 7 (http://clintons3d.com/wp/?p=109) running Marshmallow 6.0 The original guide is here https://docs.unrealengine.com/en-US/…eVR/QuickStart and my changes appear below.

1 – Google VR Project Creation
step 3 – use First Person instead of the Blank Project

This change is so there is something more than just an empty scene to start with.

2 – Google VR Project Setup
step 11 – minimum sdk version of 19 and target sdk of 24 instead of setting both to 24
step 12 – arm7 instead of arm64

These changes are needed to use a device running something older than Nougat. I think the arm64 and sdk 24 settings are mainly for Daydream phones

3 – Google VR Project Packaging & Deployment
step 1 – ETC1 instead of ASTC

https://docs.unrealengine.com/en-us/…roid/Reference
ASTC “Available on some devices at this point…”
ETC1 “Supported by all Android based devices…”

That’s it. All other instructions are the same as in the guide.

Feb 12, 2019 – the latest unreal editor 4.21.x does not work with cardboard. It builds without errors but does not run/crashes immediately. UE4.20.x is the last working version.

Ubuntu 18.04 Blu-ray

based on information found here: https://www.howtogeek.com/240487/how-to-play-dvds-and-blu-rays-on-linux/

Don’t install VLC using the Ubuntu Software button, it doesn’t seem to work for Blu-ray discs. The commands below will install a slightly older VLC version 3.0.4 Vetinari and the needed extras. The only difference from the link above is to use libbluray2 instead of libbluray1. The instructions also say ‘ Leave the “No disc menus” option checked. ‘, but it seems to work as expected with it checked.

sudo apt-get install vlc libaacs0 libbluray-bdj libbluray2
mkdir -p ~/.config/aacs/
cd ~/.config/aacs/ && wget http://vlc-bluray.whoknowsmy.name/files/KEYDB.cfg

I tried installing from the Ubuntu Software button then running the command without the vlc, “sudo apt-get install libaacs0 libbluray-bdj libbluray2”, but it did not work.

Single Page Application for Lunarpages Hosting

Quick notes for deploying a ReactJS application to a basic website hosted by Lunarpages.

  1. use the control panel to create a subdomain eg. “my-spa”
  2. add the following .htaccess file to the new folder in the public html folder – “/my-spa/”
  3. publish the production build of the SPA to the folder
  4. point browser to my-spa.mydomain.com

The extra notes in the .htaccess file are my own understanding of how it works, so reading with a critical eye is recommended.

reference links:

https://medium.com/@pshrmn/single-page-applications-and-the-server-32a23d67936

http://httpd.apache.org/docs/1.3/mod/directives.html

Contents of .htaccess file starts here:

RewriteEngine On
# set to Off to disable runtime rewriting
# set the base URL prefix
# not sure this does anything for my case
RewriteBase /
# for requests for index.html, just respond with the file
# regex ^=start, $=end, -=no substitution,[L]=last rule just do index.html
RewriteRule ^index\.html$ – [L]
# if requested path is not a valid filename, continue rewrite
# !-f=not a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# if requested path is not a valid directory, continue rewrite
# !-d=not a valid directory(treats req filename as directory)
RewriteCond %{REQUEST_FILENAME} !-d
# RewriteRule does the transformation if preceding RewriteConds are all true
# if you have continue to here, respond with index.html
# only do if preceding RewriteCond are true
# .=any single character(anything?),[L]=last rule just do index.html
RewriteRule . /index.html [L]
# source and reference info
# https://medium.com/@pshrmn/single-page-applications-and-the-server-32a23d67936
# http://httpd.apache.org/docs/1.3/mod/directives.html

Turbocad v14 and Windows 10

TurboCAD v14 does not work properly with Windows 10.

Options > Program Setup disable auto save and

Do not select the Standard style under AEC Dimension Styles in the Style Manager. This sequence will cause an instant crash.

Architecture wall dimensions will not read in. AEC dimensions are not compatible with windows 10.

To save a tcw file do not use File > Save or File > Save As…

Use File > Extract To… ,  select the Content check box to select all options then open Drawing Setup and uncheck Styles

Opening older files is still hit and miss, but new files saved via extract  seem ok.

Can also go the other way and use File > New and then File > Extract From…

Symbols via the symbol pallete cause crash. Trying to work with symbols via extract-from is a hit and miss affair, seems to only work with 3D symbols.

Can load symbols via full install of turbocad 14 pro using AddOns > SDK Samples > Insert > File.

AddOns > SDK Samples > Insert > Symbol seems to work with 3d symbols only.

Printing from model view does not center properly, so page setup values must be set manually.
From my old print notes for printing full size:
in model space
View > Create View, then define the region and give it a name

Workspace > PaperSpace > Insert, or use an existing Paper tab
switch to the paper space
Insert > Viewport then goto the previously defined paper
select the viewport rectangle and right click for it’s properties
Viewport > Scale check “Fixed”
type in the value which does not show in the dropdown list -> “1 in = 25.4 mm”

now will print to size when using the defined paper

 

Copy DV videos in Windows using FFMPEG

The goal is to convert captured DV tape avi files to DVD compatible mpg files.

cls
for %%i in ("C:\Users\Clint\Documents\TapeI"*.avi); do ffmpeg -i "%%i" -target dvd "D:\_DVrenders\%%~ni.mpg"

windows bat file to copy an avi file to mpg using ffmpeg, https://ffmpeg.org/ run from the same folder as ffmpeg binary, the bin folder, or add the binary to the environment path to run from anywhere

command can be run from the command line instead of running a bat file by changing the %% to just %

%%i == full file name in the path

%%~ni == file name without the path or extension

trueSpace + Wacom incompatible

Windows 10, Windows 7 + Wacom ET-0405-U (Graphire?) will interfere with the script editor causing slowdown when opening, editing and closing a script.

 

Workaround is to go to the Windows Control Panel > Human Interface Devices and disable the wacom driver: specifically the Wacom HID Pen

Windows10 – open device manager and disable

  1. Human Interface Devices > Wacom HID Pen
  2. Mice and other pointing devices > Wacom Mouse

Google Cardboard for Nexus 7 Notes

old_new_cardboard
Previous version was an enlarged version of the official cardboard version 1 design with larger lenses. This post is a collection of my notes taken during the process. Not a tutorial.

miniature_pieces_2miniature_pieces_1
I started by cutting out a miniature version of the official cardboard version 2 in order to understand how it goes together. It was overly complex for my needs so I developed a simplified design with the tablet sticking out the top so the screen can be used directly as an input button.

Lens info:

https://www.amazon.com/Ajax-Scientific-Double-Convex-Bi-Convex-Spherical/dp/B00EPQ9EVQ/ref=sr_1_2?ie=UTF8&qid=1478467991&sr=8-2&keywords=ajax+50+mm
Ajax Scientific Polished Glass Double-Convex (Bi-Convex) Lens, Spherical, 38 mm Diameter, 50 mm Focal Length

Lens was actually 41 mm diameter, not 38 mm

viewerbody_1600

link to turbocad file – http://clintons3d.com/download/ViewerBody_8.tcw
link to dxf file – http://clintons3d.com/download/ViewerBody_8.dxf
link to dwg file – http://clintons3d.com/download/ViewerBody_8.dwg


The viewer was assembled from 3 mm thick cardboard. The shapes were printed and taped to the cardboard to use as a template for creating the pieces. The pieces were assembled using a hot glue gun. The face and bottom pieces were covered with transparent tape to avoid oil and sweat stains on the cardboard.
Nexus 3D model from TurboSquid – http://www.turbosquid.com/FullPreview/Index.cfm/ID/762584
Artist: art_setter factory
https://vr.google.com/cardboard/manufacturers/
Profile QR-Code Generator
from desktop pc open the web page
https://vr.google.com/cardboard/viewerprofilegenerator/
then open the indicated web address in the tablet
if doesn’t work refresh the desktop web page and use the new indicated web address, repeat until it works
make adjustments on the pc until the tablet looks good then generate the qr code

My Information:
Clintons3D
Nexus7Home v2
Primary Button = Touch
Screen to lens = 45.5 mm
Inter-lens distance = 64.0 mm
Screen vertical alignment = Bottom
Distortion K1 = 0.310
Distortion K2 = 0.570
qr_viewer_profile
Note that the QR Code needs good lighting to work. Other android scanners will read it in low light, but the cardboard app needs it to be bright.

Feb 12, 2019 – google qr codes stopped working, “Unrecognized QR code”. Workaround is to use a barcode reader app and open the link in a browser, magically cardboard is setup with the proper qr code. Barcode Scanner+ worked for me. There was no indication that anything happened until after opening a vr app and seeing that the viewer changed.

Resolved (sort of) – "Unrecognized QR Code" every time I scan any QR code from GoogleCardboard

get shapes from TurboCAD into trueSpace:
remove all text and dimensions
convert circles and arcs to polylines (explode)
make closed shapes via join polylines
export scale depends on viewport scale

Sketchy Unity 3D Notes:
Got it working but a lot of fiddling around and not sure of anything
Daydream technical preview – can be used along side a regular unity install
gvr unity sdk – for samples
to find SDK and JDK path for modern Android Studio
open Android Studio
File > Settings
Appearance & Behavior > System Settings > Android SDK – will show the location for the SDK
The JDK is at C:\Program Files\Android\Android Studio\jre
These path values go into Unity – Edit > Preferences > External Tools
Also enable VR support and set API level 19 also download api 19 inside android studio
Latest Daydream Unity has lag/frame rate problems?

TurboCAD Side Notes: TurboCAD v14 does not work properly with Windows 10. Use of AEC Dimension Styles will cause instant crash. Text tools cause instant crash. The workaround is to save files to v12 format files and ignore the warning messages when using copy and paste. If file is v14 immediately save as v12, close file and reload it. Features unique to v14 will not fully save to v12, but it wasn’t an issue for this project. Printing from model view does not center properly, so page setup values must be set manually.
From old print notes:
in model space
View > Create View, then define the region and give it a name

Workspace > PaperSpace > Insert, or use an existing Paper tab
switch to the paper space
Insert > Viewport then goto the previously defined paper
select the viewport rectangle and right click for it’s properties
Viewport > Scale check “Fixed”
type in the value which does not show in the dropdown list -> “1 in = 25.4 mm”

now will print to size when using the defined paper

New information(Feb 2018) about turbocad problems in windows 10.

To save a tcw file do not use File > Save or File > Save As…

Use File > Extract To… ,  select the Content check box then open Drawing Setup and uncheck Styles