Make Hollow?
by John Spivey · in Artist Corner · 07/07/2006 (5:32 pm) · 12 replies
Do you guys exspect to have a make hollow function in by 1.0? Its a nice feature that I would personally like to see in constructor. Just wondering.
#2
07/10/2006 (5:31 pm)
Are there any docs on the tool api? I took a walk through the script files and found dozens of tool calls. I'm wondering if there was a specific area that had a good example from which to build from.
#3
07/10/2006 (6:09 pm)
I also noticed breakpoints do not work. Did I miss something, or has script debugging been disabled?
#4
We haven't rolled the enhanced script debugger into the Constructor codebase so Torsion and Codeweaver probably won't work correctly. I will add that to a todo list but it is a lower priority for the moment (behing Undo, new texture tools, and Direct-to-dif).
07/10/2006 (6:59 pm)
There are docs. I will be sure to bundle them into the next Beta release and start looking to get them onto the wiki soon.We haven't rolled the enhanced script debugger into the Constructor codebase so Torsion and Codeweaver probably won't work correctly. I will add that to a todo list but it is a lower priority for the moment (behing Undo, new texture tools, and Direct-to-dif).
#5
07/10/2006 (8:22 pm)
@Matt: No rush, I was just making sure I hadn't missed something obvious. Great work on the script documentation BTW. I spent some time looking at the code today, and was impressed with the job you guys are doing. Keep up the great work.
#6
I've just placed my Excel spreadsheet listing many of the script methods and functions available in Constructor. It isn't yet complete (it is missing all direct InteriorMap methods) and I have to reserve the right to make sweeping changes. :o)
You may find it on the new Constructor docs page here.
Here's the tabs you'll like be interested in:
tool - Deals with the Tool Manager and lists all valid flags and return types for tool plug-ins.
ToolDrawing - Methods and flags used to draw a tool's interface
ToolEdit - Methods and flags used to manipulate a scene through the Tool Manager. These provide buffers for the tool to help with general operation and is the usual method for a tool to work with a scene. However the tool is free to use all available script methods if it knows what it is doing.
ToolInterface - Methods used to build out the standard tool interface as found under the Tool Properties Form.
DynamicControls - The various types of standard controls that are available for a tool's interface.
I'll put all this information into TDN at some point. Hopefully this will get you and others started. I'm of course interested in any feedback as up to this point I'm the only one that is writing tools against my own interface, which is not the best way to test. :o)
- LightWave Dave
07/14/2006 (9:40 am)
Greetings Brandon!I've just placed my Excel spreadsheet listing many of the script methods and functions available in Constructor. It isn't yet complete (it is missing all direct InteriorMap methods) and I have to reserve the right to make sweeping changes. :o)
You may find it on the new Constructor docs page here.
Here's the tabs you'll like be interested in:
tool - Deals with the Tool Manager and lists all valid flags and return types for tool plug-ins.
ToolDrawing - Methods and flags used to draw a tool's interface
ToolEdit - Methods and flags used to manipulate a scene through the Tool Manager. These provide buffers for the tool to help with general operation and is the usual method for a tool to work with a scene. However the tool is free to use all available script methods if it knows what it is doing.
ToolInterface - Methods used to build out the standard tool interface as found under the Tool Properties Form.
DynamicControls - The various types of standard controls that are available for a tool's interface.
I'll put all this information into TDN at some point. Hopefully this will get you and others started. I'm of course interested in any feedback as up to this point I'm the only one that is writing tools against my own interface, which is not the best way to test. :o)
- LightWave Dave
#7
I'm going to look play with this a bit before bed. I'm assuming I'll be able to mess with this a little with Beta4. I know you said on TDN that Beta5 had the menu item to run plugins, but I'll play with this a bit now just becuase I've been in the mood to do something different.
B--
07/14/2006 (8:32 pm)
Wow Dave! Nice excel document, that should get things moving along nicely. I think you should be nominated for the GG 1st anual "Best documentation" award. I usually comment my code extensively, but you've got me beat in presentation alone! :)I'm going to look play with this a bit before bed. I'm assuming I'll be able to mess with this a little with Beta4. I know you said on TDN that Beta5 had the menu item to run plugins, but I'll play with this a bit now just becuase I've been in the mood to do something different.
B--
#8
Yes you should be able to play with tools in Beta4. Placing your script files in the constructor/client/plug-ins directory should still have them auto-load. The main difference is that you'll be missing the nice menu to activate your plug-in. Instead you'll have to use the console:
- LightWave Dave
07/14/2006 (9:18 pm)
Thanks Brandon.Yes you should be able to play with tools in Beta4. Placing your script files in the constructor/client/plug-ins directory should still have them auto-load. The main difference is that you'll be missing the nice menu to activate your plug-in. Instead you'll have to use the console:
tool.activate(YourToolPackageName);
- LightWave Dave
#9
Next up, I'll see if I can get access to the size of a selected brush to use it as a starting point for the scaled down brush used for the hollow. Looks like it shouldn't be too hard considering the way you have everything setup. It's been awhile since I've spent any time with tScript, so it has been a pretty fun couple of hours getting back into the swing of things. I must admit, I feel naked without a debugger! haha! I think I've gotten spoiled considering my humble beginnings of using print""; to debug basic on a vic-20 and c-64.
As far as initial feedback on the Tool API, I love it! Consistent implementation that seems to cover all the bases, object oriented approach, extensible, and well documented. It looks great so far.
Well, time for bed, thanks again for the excel doc, it has been a big help getting a good grasp on what is available, and the floorplan you have established. I'll play with this more tomorrow.
B--
07/14/2006 (11:15 pm)
@Dave: Yeah, I just added some new buttons to the interface to streamline execution and commands. (yes, I'm too lazy to type in the console any more than I have to :) ) Nice work on the Tool API from what I've played with so far. At this point I just created a couple of new tools from existing ones to get a feel for the general flow that has been established. I started with the addentity, and then modified the cube tool. I really like the reusable object oriented framework that has been achieved using torquescript.Next up, I'll see if I can get access to the size of a selected brush to use it as a starting point for the scaled down brush used for the hollow. Looks like it shouldn't be too hard considering the way you have everything setup. It's been awhile since I've spent any time with tScript, so it has been a pretty fun couple of hours getting back into the swing of things. I must admit, I feel naked without a debugger! haha! I think I've gotten spoiled considering my humble beginnings of using print""; to debug basic on a vic-20 and c-64.
As far as initial feedback on the Tool API, I love it! Consistent implementation that seems to cover all the bases, object oriented approach, extensible, and well documented. It looks great so far.
Well, time for bed, thanks again for the excel doc, it has been a big help getting a good grasp on what is available, and the floorplan you have established. I'll play with this more tomorrow.
B--
#10
This gets a little slow when there are many brushes in the scene becasue the performCSGSubtraction checks everything in the scene against the cut brush.
To use the tool select at least one brush and activate the tool. If you have multiple brushes selected, it will perform multiple cuts as if you did them one at a time.
Installing it is easy enough.. Just make a file called csghollow.cs in your ./constructor/client/plug-ins folder, and paste the code below in it. To activate the tool, select tools / user plug-ins / CSG Hollow from the top menu of Constructor with at least one brush selected.
This was my first time to sit down and actually make something with the Tool API. Now that I've spent a few hours playing with it I have many suggestions and comments for the Tool API! haha
Brandon.
07/19/2006 (11:07 am)
Here is a rough implementation of a CSG Hollow. At this point it is hard coded for walls that are 0.1 meters thick, and so far works with all the primitives in Constructor. The hard coded thickness amount is located in the Plugin::Execute as %THICKNESS. When you use this tool you will also lose anything in your clipboard since it uses the copy/paste features of the interface.This gets a little slow when there are many brushes in the scene becasue the performCSGSubtraction checks everything in the scene against the cut brush.
To use the tool select at least one brush and activate the tool. If you have multiple brushes selected, it will perform multiple cuts as if you did them one at a time.
Installing it is easy enough.. Just make a file called csghollow.cs in your ./constructor/client/plug-ins folder, and paste the code below in it. To activate the tool, select tools / user plug-ins / CSG Hollow from the top menu of Constructor with at least one brush selected.
//
// csghollow.cs
//
// Defines the csghollow tool plug-in to hollow a brush by a specific amount.
//
// Revision History:
// July 19, 2006 David Wyand Created script file
// B--
package CSGHollow
{
//************************************************************************************
//*** Standard Tool Functions
//************************************************************************************
//************************************************************************************
// Activate()
//
// Called when the tool is activated. %version holds the current version of this
// tool type in Constructor to allow the tool to step down features if required.
// %inst is actually a ScriptObject behind the scenes that allows for the tool's
// instance to be attached to it -- which is typically a ScriptObject itself.
// %static is a ScriptObject that allows anything to be attached to it that will
// presist across tool instances.
// Return a Tool Return Function to indicate success of the tool's activation.
function Plugin::Activate(%this, %version, %inst, %static)
{
error("CSGHollow: Activate(" @ %version @ "," @ %inst @ "," @ %static @ ")");
//*** Check for a valid version
if(%version != 1)
{
return tool.FUNC_BADVERSION();
}
//*** This tool doesn't need to make use of the instance
%inst.instance = 0;
%inst.flagsInterface = tool.IFLAG_NONE(); // No special interface flags as there will be no interface
%inst.flagsApply = tool.AFLAG_NONE(); // No special actions when tool is applied
//*** Return that everything is OK
return tool.FUNC_OK();
}
//************************************************************************************
// Done()
//
// Called when the user is finished with the tool. Typically any allocated
// memory is freed here. %inst and %static are the same as those in the
// activation function. This function does not return a value.
function Plugin::Done(%this, %inst, %static)
{
error("CSGHollow: Done(" @ %inst @ "," @ %static @ ")");
%plugin = %inst.instance;
if(%plugin)
{
//*** Delete our instance
%plugin.delete();
%inst.instance = 0;
}
}
//************************************************************************************
// Execute()
//
// This function is called to perform the actual work of the tool, and does not
// return a value.
function Plugin::Execute(%this, %inst)
{
error("CSGHollow: Execute(" @ %inst @ ")");
//*** Hollow thickness hard coded at this point..
%THICKNESS = "0.1";
if(scene.getCurrentMap().getSelectedBrushes() $= "")
{
MessageBoxOK("No Brushes Selected", "Select at least 1 brush to hollow!");
error("Select at least 1 brush");
}
else
{
//*** Lets start by making a copy of everything selected and scale it down
//*** so we can use it for a cut brush
select.copy(); //doing this opens the door for multiple hollows at once
select.paste();
%currMap = scene.getCurrentMap();
%currBrushSelections = %currMap.getSelectedBrushes();
%totalBrushesSelected = getWordCount(%currBrushSelections);
for(%i = 0; %i < %totalBrushesSelected; %i++) //handles multiple hollows
{
select.clear();
select.addItem(getWord(%currBrushSelections, %i));
%currBrush = %currMap.getSelectedBrushes(); //focus on the current brush
error("loop:" @ %i @ "Brush:" @ %currMap.getSelectedBrushes());
%hollowScale = CSGHollow_GetScale(%currMap.getSelectedBrushesBounds(), %THICKNESS); //custom routine to get scale amount
%currMap.setBrushScale(%currBrush, %hollowScale); //handy scale that keeps center
//%currMap.performCSGSubtraction($currBrush); //not sure why this didn't work?
scene.getCurrentMap().performCSGSubtraction(scene.getCurrentMap().getSelectedBrushes());
select.deleteSelection(%currBrush); //get rid of cut brush
}
}
scene.notifyBrushRefresh();
}
//************************************************************************************
//*** Tool Specific Functions
//************************************************************************************
//*** Get BrushSize from bounds box min and max
function CSGHollow_GetBrushSize(%bbox)
{
%min[0] = getWord(%bbox,0); //min x
%min[1] = getWord(%bbox,1); //min y
%min[2] = getWord(%bbox,2); //min z
%max[0] = getWord(%bbox,3); //max x
%max[1] = getWord(%bbox,4); //max y
%max[2] = getWord(%bbox,5); //max z
%x = %max[0] - %min[0]; //max - min equals the size of x
%y = %max[1] - %min[1];
%z = %max[2] - %min[2];
//error("SIZE:" @ %x SPC %y SPC %z);
return(%x SPC %y SPC %z); //send back x y z
}
//*** Get the correct scale to perform a hollow of a specific thickness
//The %thickness is the actual thickness, so if you want walls that are 0.1
//meters thick, just pass in 0.1
function CSGHollow_GetScale(%bounds, %thickness)
{
%brushSize = CSGHollow_GetBrushSize(%bounds); //turn bounds into xyz size
%totalThickness = %thickness * 2; //thickness is for one side only, so multiply by 2
%x = getWord(%brushSize, 0); //grab the x size
%y = getWord(%brushSize, 1);
%z = getWord(%brushSize, 2);
%nx = %x - %totalThickness; //subtract thickness from size
%ny = %y - %totalThickness;
%nz = %z - %totalThickness;
%scaleX = %nx / %x; //get correct scale by dividing new smaller size by original size
%scaleY = %ny / %y;
%scaleZ = %nz / %z;
//error("NEWSCALE:" @ %scaleX SPC %scaleY SPC %scaleZ);
return(%scaleX SPC %scaleY SPC %scaleZ); //reutrn new xyz scale values
}
};
tool.register("CSGHollow", tool.typeGeneric(), tool.RFLAG_NONE(), "CSG Hollow" );This was my first time to sit down and actually make something with the Tool API. Now that I've spent a few hours playing with it I have many suggestions and comments for the Tool API! haha
Brandon.
#11
Very nice Brandon. I'll give it a try later today.
I wanted to let you know that a silly bug made it into Beta 5 with the Tool Manager that prevents more than one user plug-in to show up in the menu bar. I believe you guys have the script source, so open toolmanager.cs and find the CToolManager::loadToolPlugins() method. Make the following bolded change:
And that should do it.
- LightWave Dave
07/19/2006 (11:43 am)
Greeting!Very nice Brandon. I'll give it a try later today.
I wanted to let you know that a silly bug made it into Beta 5 with the Tool Manager that prevents more than one user plug-in to show up in the menu bar. I believe you guys have the script source, so open toolmanager.cs and find the CToolManager::loadToolPlugins() method. Make the following bolded change:
//*** Go through each of the plug-in tool scripts and launch them
$ToolManagerToolPluginFileName = "";
$ToolManagerToolPluginType = "Plug-in";
$ToolManagerToolUserPluginCounter = $StartOfUserPluginsMenuID;
echo("Loading plug-ins...");
for(%file = findFirstFile($UserPluginDirectory); %file !$= ""; %file = findNextFile([b]$UserPluginDirectory[/b]))
{
//*** Execute the plug-in's script
$ToolManagerToolPluginFileName = %file;
exec(%file);
$ToolManagerToolUserPluginCounter++;
}
echo("...Done");
$ToolManagerToolPluginFileName = "";
$ToolManagerToolPluginType = "";And that should do it.
- LightWave Dave
#12
EDIT: The %inst.thickness variable mistake also made me think it was not working with the other primitives, but all of them hollow correctly now.
B--
07/19/2006 (12:14 pm)
@Dave: Worked like a charm. I hadn't even noticed it because I'm using a button for the hollow. I edited the code post above. Before posting the code I had moved the %thickness into Plugin::Activate and stored it in %inst.thickness. I didn't think much of it, but that doesn't work so well! Anyways, I just put it back in the Plugin::Execute as %THICKNESSEDIT: The %inst.thickness variable mistake also made me think it was not working with the other primitives, but all of them hollow correctly now.
B--
Associate Matt Fairfax
Night Heron Games
Doing a hollow is pretty straightforward even with the current setup. Just copy/paste the brush, scale it up or down evenly on all the axii, make sure their center points line up, and do a CSG Difference operation.
Bam! Instant hollowing action =)
This could be a fun exercise for someone to attempt to make a new script Tool for to help us work out design issues with the tool API.