Category Archives: Uncategorized

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

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 General SDK Notes(copied from wiki)

To change the version of a plugin from v.1638401 in the plugin manager change the RpExamplesPlugin.h from
#define EXAMPLE_PACKAGE_VERSION1 1 // cmdprompt package version

#define EXAMPLE_PACKAGE_VERSION EXAMPLE_PACKAGE_VERSION1

to

#define EXAMPLE_PACKAGE_VERSION1 1 // cmdprompt package version

//#define EXAMPLE_PACKAGE_VERSION EXAMPLE_PACKAGE_VERSION1

#define EXAMPLE_PACKAGE_06192010 3 //my june 19 2010 version

#define EXAMPLE_PACKAGE_VERSION EXAMPLE_PACKAGE_06192010

will change the version to v.1635403
//from kernel.h

   //enum RtPixelFormat
   //{   
   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;
  // } ;

trueSpace General Script Notes(copied from wiki)

Clinick’s Clinic on Scripting #1: VBScript or JScript?

Special Edition Using Jscript, Including OOP in chapter 4

  1. Node.NearValue script property. Similar to Node.Value, but allows to specify short node name, if you want to access neighbor node from your script.
   * So instead of:
         o Node.Value( System.ThisOwner + “/Memory”, “A”) = 10
   * You can now use:
         o Node.NearValue( “Memory”, “A”) = 10
  1. Node.LookupParentValue script property (get only). The property look up parents for specified connector value. This can be useful for larger script projects with hierarchical structure – to access ‘common project parameters’ from all activity bricks without need to link to exported connector.
   * Example:
         o numPlayers = Node.LookupParentValue(“numPlayers”)
  1. Per widget visible/invisible settings in Desktop preferences.
   * Widgets saved in \scripts\desktop.widgets.xml, you can add your custom widgets here.

The way I understand the RsPackage.Install() command, it creates and or writes to the Plugins.xml file located in the Scripts folder. When you open tS761 the init.js file runs. In this script you will notice the RsPackage.Import(‘plugins.xml’); command. I believe the reset.js runs when a user Resets the Default Context. In that script you will notice two commands: ScriptObject.ImportScripts(0); ScriptObject.UpdatePck(0); As I understand it, this command reads the Scripts/ScriptCommands folder and loads all of the scripts within, into tS761 in the System/Scripts/Commands node. The scripts have to be named from within the Script Editor’s Attribute area in order for this to work right. This is how I loaded all of the scripts included in the last Unofficial Update. You will notice an OnNewScene script which gets called when you run Generate New Scene.

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

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

Scripts with the same command input connection will run in the order that they are connected. No parallel processing from parallel connections.

Script can combine different selection types like edge plus triangle.
sdk docs “structIRiTSBCommand.html” has “SuggestTSStateByAlias” command which is used to “Call to execute a Modeler’s action(click on a Modeler’s button)”. download Hexplorer http://sourceforge.net/projects/hexplorer/

and running it on the tsxapi.dll file. Do a search for “Button” and one by one you can find the aliases for all the modelside buttons. Also works with items found by searching for “Panel”.

Modelspace(trueSpace 6) Button Icon production

24 bit bmp format, background color about (192,192,192), size 30×22

Workspace Button Icon production

truespace button icon –

paint shop pro 32 bit tga, background color about (118,118,118), select background, invert and save to alpha, size 26×26
photoshop – same, but can also do bmp format in 32bit

Link Editor Panels Editor

   * Tab order edit field in control property window.
   * Expand / shrink control size functions.
         o expand enlarges object size until it touches neighboring controls.
         o shrink minimizes size of selected object so that it fits a gap under the control.
   * Controls snapping in Panel Editor:
         o edges of the selected control are snapped to edges of remaining controls during panel editing.
         o this feature can be turned off in panel properties dialog.
   * Decorative control
         o use it to fill empty spaces, to create separating lines and to create "radio group"-like looking panel
   *
         o use "fill gaps" function (located in decorative control properties dialog) to automaticaly clone this control to every hole in the panel
   *
         o use Bottom/Right checkbox to fine-tune line position or to change orientation of the "U" shape
   * moving edited control using arrows snaps to grid and other controls too
   * hold ctrl while moving edited control to turn of snapping
   * Holding shift while sizing a control resizes all controls in the same row/column.

If you add a new connector to a script used inside the Widgets it won’t work right away. Restarting truespace will unstick it.
MeshModifiers.WeldPairs() script command does not work. It is the script version of the Edge Weld Tool for trueSpace 7.1

//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() + "}");

}

//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() + “}”);

}

Toolbar Prototype notes

create a toolbar by normal means – will often end up in a frame named “ToolbarFrame”

find the Toolbar inside Windows Manager Space inside the ToolbarFrame

type a name into the Prototype field of the Toolbar node and a prototype will be created inside the Toolbar Prototype Encapsulator

to recreate the toolbar – create a toolbar(drag and drop a button from another toolbar), find it’s Toolbar node and type the same name into the Prototype field and the toolbar will be recreated

OpenToolbarfromPrototype does not return the name of the node created
WScript Shell

//WshShell = WScript.CreateObject(“WScript.Shell”);

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
 

C++ handle to window

truespace 6

HWND tswnd;
tswnd = tsxGetMainViewHwnd();

truespace 7.6

HRESULT hr;
HWND tswnd;
// get Window manager package
CComPtr spKernelPackage;
hr = CRpExamplesPlugin::GetKernelPackage(&spKernelPackage);
if (FAILED(hr))
   return hr;
CComPtr spPackage;
hr = spKernelPackage->FindPackage(DEF_GUIDNAME(CRpWinMng), &spPackage);
if (FAILED(hr))
   return hr;
CComQIPtr spWinPackage = spPackage;
// get windows manager node
CComPtr spWinMgrNode;
hr = spWinPackage->GetWindowsManagerNode(&spWinMgrNode);
if (FAILED(hr))
   return hr;
CComQIPtr spWinMng = spWinMgrNode;
spWinMng->get_MainWindowHandle(&tswnd);