|
TSShapeConstructor Class Reference
[Game Objects]
An object used to modify a DTS or COLLADA shape model after it has been loaded by Torque. More...
Public Member Functions | |
bool | addCollisionDetail (int size, string type, string target, int depth=4, float merge=30, float concavity=30, int maxVerts=32, float boxMaxError=0, float sphereMaxError=0, float capsuleMaxError=0) |
Autofit a mesh primitive or set of convex hulls to the shape geometry. Hulls may optionally be converted to boxes, spheres and/or capsules based on their volume. | |
int | addImposter (int size, int equatorSteps, int polarSteps, int dl, int dim, bool includePoles, float polarAngle) |
Add (or edit) an imposter detail level to the shape. | |
bool | addMesh (string meshName, string srcShape, string srcMesh) |
Add geometry from another DTS or DAE shape file into this shape. | |
bool | addNode (string name, string parentName, TransformF txfm=TransformF::Identity, bool isWorld=false) |
Add a new node. | |
bool | addPrimitive (string meshName, string type, string params, TransformF txfm, string nodeName) |
Add a new mesh primitive to the shape. | |
bool | addSequence (string source, string name, int start=0, int end=-1, bool padRot=true, bool padTrans=false) |
Add a new sequence to the shape. | |
bool | addTrigger (string name, int keyframe, int state) |
Add a new trigger to the sequence. | |
void | dumpShape (string filename="") |
Dump the shape hierarchy to the console or to a file. Useful for reviewing the result of a series of construction commands. | |
Box3F | getBounds () |
Get the bounding box for the shape. | |
int | getDetailLevelCount () |
Get the total number of detail levels in the shape. | |
int | getDetailLevelIndex (int size) |
Get the index of the detail level with a given size. | |
string | getDetailLevelName (int index) |
Get the name of the indexed detail level. | |
int | getDetailLevelSize (int index) |
Get the size of the indexed detail level. | |
int | getImposterDetailLevel () |
Get the index of the imposter (auto-billboard) detail level (if any). | |
string | getImposterSettings (int index) |
Get the settings used to generate imposters for the indexed detail level. | |
int | getMeshCount (string name) |
Get the number of meshes (detail levels) for the specified object. | |
string | getMeshMaterial (string name) |
Get the name of the material attached to a mesh. Note that only the first material used by the mesh is returned. | |
string | getMeshName (string name, int index) |
Get the name of the indexed mesh (detail level) for the specified object. | |
int | getMeshSize (string name, int index) |
Get the detail level size of the indexed mesh for the specified object. | |
string | getMeshType (string name) |
Get the display type of the mesh. | |
int | getNodeChildCount (string name) |
Get the number of children of this node. | |
string | getNodeChildName (string name, int index) |
Get the name of the indexed child node. | |
int | getNodeCount () |
Get the total number of nodes in the shape. | |
int | getNodeIndex (string name) |
Get the index of the node. | |
string | getNodeName (int index) |
Get the name of the indexed node. | |
int | getNodeObjectCount (string name) |
Get the number of geometry objects attached to this node. | |
string | getNodeObjectName (string name, int index) |
Get the name of the indexed object. | |
string | getNodeParentName (string name) |
Get the name of the node's parent. If the node has no parent (ie. it is at the root level), return an empty string. | |
TransformF | getNodeTransform (string name, bool isWorld=false) |
Get the base (ie. not animated) transform of a node. | |
int | getObjectCount () |
Get the total number of objects in the shape. | |
int | getObjectIndex (string name) |
Get the index of the first object with the given name. | |
string | getObjectName (int index) |
Get the name of the indexed object. | |
string | getObjectNode (string name) |
Get the name of the node this object is attached to. | |
string | getSequenceBlend (string name) |
Get information about blended sequences. | |
int | getSequenceCount () |
Get the total number of sequences in the shape. | |
bool | getSequenceCyclic (string name) |
Check if this sequence is cyclic (looping). | |
int | getSequenceFrameCount (string name) |
Get the number of keyframes in the sequence. | |
string | getSequenceGroundSpeed (string name) |
Get the ground speed of the sequence. | |
int | getSequenceIndex (string name) |
Find the index of the sequence with the given name. | |
string | getSequenceName (int index) |
Get the name of the indexed sequence. | |
float | getSequencePriority (string name) |
Get the priority setting of the sequence. | |
string | getSequenceSource (string name) |
Get information about where the sequence data came from. | |
int | getTargetCount () |
Get the number of materials in the shape. | |
string | getTargetName (int index) |
Get the name of the indexed shape material. | |
string | getTrigger (string name, int index) |
Get information about the indexed trigger. | |
int | getTriggerCount (string name) |
Get the number of triggers in the specified sequence. | |
void | notifyShapeChanged () |
Notify game objects that this shape file has changed, allowing them to update internal data if needed. | |
bool | removeDetailLevel (int index) |
Remove the detail level (including all meshes in the detail level). | |
bool | removeImposter () |
Remove the imposter detail level (if any) from the shape. | |
bool | removeMesh (string name) |
Remove a mesh from the shape. | |
bool | removeNode (string name) |
Remove a node from the shape. | |
bool | removeObject (string name) |
Remove an object (including all meshes for that object) from the shape. | |
bool | removeSequence (string name) |
Remove the sequence from the shape. | |
bool | removeTrigger (string name, int keyframe, int state) |
Remove a trigger from the sequence. | |
bool | renameDetailLevel (string oldName, string newName) |
Rename a detail level. | |
bool | renameNode (string oldName, string newName) |
Rename a node. | |
bool | renameObject (string oldName, string newName) |
Rename an object. | |
bool | renameSequence (string oldName, string newName) |
Rename a sequence. | |
void | saveShape (string filename) |
Save the shape (with all current changes) to a new DTS file. | |
bool | setBounds (Box3F bbox) |
Set the shape bounds to the given bounding box. | |
int | setDetailLevelSize (int index, int newSize) |
Change the size of a detail level. | |
bool | setMeshMaterial (string meshName, string matName) |
Set the name of the material attached to the mesh. | |
bool | setMeshSize (string name, int size) |
Change the detail level size of the named mesh. | |
bool | setMeshType (string name, string type) |
Set the display type for the mesh. | |
bool | setNodeParent (string name, string parentName) |
Set the parent of a node. | |
bool | setNodeTransform (string name, TransformF txfm, bool isWorld=false) |
Set the base transform of a node. That is, the transform of the node when in the root (not-animated) pose. | |
bool | setObjectNode (string objName, string nodeName) |
Set the node an object is attached to. | |
bool | setSequenceBlend (string name, bool blend, string blendSeq, int blendFrame) |
Mark a sequence as a blend or non-blend. | |
bool | setSequenceCyclic (string name, bool cyclic) |
Mark a sequence as cyclic or non-cyclic. | |
bool | setSequenceGroundSpeed (string name, Point3F transSpeed, Point3F rotSpeed=Point3F::Zero) |
Set the translation and rotation ground speed of the sequence. | |
bool | setSequencePriority (string name, float priority) |
Set the sequence priority. | |
void | writeChangeSet () |
Write the current change set to a TSShapeConstructor script file. The name of the script file is the same as the model, but with .cs extension. eg. myShape.cs for myShape.dts or myShape.dae. | |
Callbacks | |
void | onLoad () |
Called immediately after the DTS or DAE file has been loaded; before the shape data is available to any other object (StaticShape, Player etc). This is where you should put any post-load commands to modify the shape in-memory such as addNode, renameSequence etc. | |
void | onUnload () |
Called when the DTS or DAE resource is flushed from memory. Not normally required, but may be useful to perform cleanup. | |
Public Attributes | |
Collada | |
bool | adjustCenter |
Translate COLLADA model on import so the origin is at the center. No effect for DTS files. | |
bool | adjustFloor |
Translate COLLADA model on import so origin is at the (Z axis) bottom of the model. No effect for DTS files. | |
string | alwaysImport |
TAB separated patterns of nodes to import even if in neverImport list. No effect for DTS files. | |
string | alwaysImportMesh |
TAB separated patterns of meshes to import even if in neverImportMesh list. No effect for DTS files. | |
bool | forceUpdateMaterials |
Forces update of the materials.cs file in the same folder as the COLLADA (.dae) file, even if Materials already exist. No effect for DTS files. | |
bool | ignoreNodeScale |
Ignore <scale> elements inside COLLADA <node>s. No effect for DTS files. | |
TSShapeConstructorLodType | lodType |
Control how the COLLADA (.dae) importer interprets LOD in the model. No effect for DTS files. | |
string | matNamePrefix |
Prefix to apply to all material map names in the COLLADA (.dae) file. No effect for DTS files. | |
string | neverImport |
TAB separated patterns of nodes to ignore on loading. No effect for DTS files. | |
string | neverImportMesh |
TAB separated patterns of meshes to ignore on loading. No effect for DTS files. | |
int | singleDetailSize |
Sets the detail size when lodType is set to SingleSize. No effect otherwise, and no effect for DTS files. | |
float | unit |
Override the <unit> element in the COLLADA (.dae) file. No effect for DTS files. | |
TSShapeConstructorUpAxis | upAxis |
Override the <up_axis> element in the COLLADA (.dae) file. No effect for DTS files. | |
Media | |
filename | baseShape |
Specifies the path to the DTS or DAE file to be operated on by this object. | |
Sequences | |
filename | sequence |
Legacy method of adding sequences to a DTS or DAE shape after loading. |
Detailed Description
An object used to modify a DTS or COLLADA shape model after it has been loaded by Torque.
TSShapeConstructor is a special object used to modify a DTS or COLLADA shape model after it has been loaded by Torque, but before it is used by any other object.
It is often used to share animations from DSQ files between shapes with a common skeleton.
It may also be used to 'Torquify' a model that is missing the nodes and/or sequences required to function as a particular Torque object. A model used for a Player character for example should have an eye and a cam node, but these might not be present in a model not specifically created for Torque. TSShapeConstructor allows the missing nodes to be added and positioned so that the shape does not need to be re-worked or re-exported by an artist.
- Note:
- In T3D, TSShapeConstructor is no longer a SimDataBlock (like in TGE and TGEA), but a SimObject instead. This means that all declarations of TSShapeConstructor should use the singleton keyword instead of the datablock keyword.
TSShapeConstructor also includes features to aid in loading COLLADA models, such as allowing the <up_axis> and <unit> elements to be overridden, and can also apply a user specified prefix to the names of COLLADA materials as shown below. Prefixing material names is useful to avoid name clashes, particularly for 3D apps like Google SketchUp that export models with generic material names like "material0". These options are most easily accessed using the COLLADA import gui, which will be displayed automatically the first time a COLLADA model is imported into Torque.
Settings from the import gui are automatically saved to a TSShapeConstructor script in the same folder as the model.
To create your own TSShapeConstructor object, simply create a TorqueScript file in the same folder as your DTS or COLLADA model, with the same filename but .cs extension. For example, if your model file was called myShape.dts, you would create a file called myShape.cs. Some example appear below:
singleton TSShapeConstructor( MyShapeDae ) { baseShape = "./myShape.dae"; upAxis = "DEFAULT"; // use <up_axis> defined in myShape.dae unit = "1.0"; // override <unit> to be 1.0 matNamePrefix = ""; // no prefix applied to collada materials };
singleton TSShapeConstructor( MyShape2Dae ) { baseShape = "./myShape2.dae"; upAxis = "Y_AXIS"; // override <up_axis> to be Y_AXIS unit = -1; // use <unit> defined in myShape2.dae matNamePrefix = "myShape2_"; // prefix all collada material names with "myShape2_" }
The name of the TSShapeConstructor object (MyShapeDae and MyShape2Dae in the code samples above) is up to you, but you should choose a name that does not conflict with other objects or datablocks. A common convention for TSShapeConstructor objects is the name of the shape file. eg. MyShapeDae for a file called myshape.dae.
When Torque loads a DTS (.dts) or COLLADA (.dae) file, it first looks in the same folder for a TorqueScript file with the same filename (but .cs extension) in order to create the TSShapeConstructor object. Such scripts are executed automatically by Torque 3D, so there is no need to manually call exec("myShape.cs") from another script. Also, you should avoid adding other object and datablock declarations to this script because it will be executed every time the model is loaded, which may cause unexpected results if the datablocks already exist.
After Torque has loaded the model from the DTS or COLLADA file, it executes the TSShapeConstructor onLoad method to apply the desired set of changes to the shape. It should be noted that the changes are applied to the loaded model in memory rather than to the DTS or COLLADA file itself. This means the model can be re-exported to DTS or COLLADA without overwriting the TSShapeConstructor changes. TSShapeConstructor should be thought of as a post-export processing step, and is intended to be used alongside existing object and datablock setups.
Note that DSQ sequences may still be specified within the TSShapeConstructor object as normal:
singleton TSShapeConstructor( PlayerDts ) { baseShape = "./player.dts"; sequence = "~/art/shapes/actors/animations/player_root.dsq root"; sequence = "~/art/shapes/actors/animations/player_forward.dsq run"; }; function PlayerDts::onLoad( %this ) { %this.addCollisionDetail( -1, "box", "bounds" ); // collision mesh %this.addSequence( "walk", "walk_short", 1, 5 ); // add subsequence %this.addTrigger( "walk_short", 3, 4 ); // add trigger to sequence %this.renameSequence( "walk", "walk_long" ); // rename sequence %this.renameNode( "Bip Pelvis", "pelvis" ); // rename node %this.addNode( "mount5", "Bip L Hand" ); // add a new node %this.dumpShape(); // dump shape to console }
Note that most of the features in TSShapeConstructor are far more easily accessible in the Shape Editor tool. This tool uses TSShapeConstructor 'under-the-hood' to edit the nodes, sequences and details of a shape, and the changes are saved to a TSShapeConstructor script object.
Shape Terminology
The following definitions should be understood before reading the TSShapeConstructor examples and function reference:
- node
- A node is a place-holder for transform (position and rotation) information. Nodes are arranged in a parent/child hierarchy allowing complex skeleton structures to be built up.
- sequence
- A sequence is a set of keyframed node transforms and object states (eg. visibility).
- detail level
- Level-of-Detail (LOD) is very important to maintain good rendering performance. When a shape is rendered, Torque automatically picks a single detail level based on that shape's on-screen size. Only the sub-meshes belonging to that detail level are rendered.
- object
- An object is a collection of meshes, each at a different detail level. Each object is attached to a certain node, and is rendered at that node's current transform.
- mesh
- A mesh is a piece of geometry, and may be a rigid body or a skin (vertex weighted mesh). Each mesh is associated with an object and a certain detail level.
Example 1: Adding a Collision Mesh To an Existing Shape
Imagine you have a model that you want to add to the scene as a StaticShape, but it is missing a collision mesh. TSShapeConstructor makes it simple to modify an existing DTS shape to add a collision (or line-of-sight collision) detail level.
First, define the StaticShapeData datablock as normal. Create a script called myShape.cs in the art/datablocks folder, and define the datablock:
datablock StaticShapeData( MyShapeData ) { category = "Misc"; shapeFile = "art/shapes/myShape/myShape.dts"; };
We need to tell Torque to execute this script so add exec("./myShape.cs"); to art/datablocks/datablockExec.cs.
Now we define the TSShapeConstructor object by creating a new script called myShape.cs in the art/shapes/myShape folder:
singleton TSShapeConstructor( MyShapeDts ) { baseShape = "~/art/shapes/myShape/myShape.dts"; }; function MyShapeDts::onLoad( %this ) { %this.addCollisionDetail( -1, "box", "bounds" ); }
This script will add a box mesh with the same center and dimensions as the original model using the "Col" detail level at size -1. The negative detail size means that the mesh will not be rendered in-game, and the use of the special "Col" name means that this mesh will be detected as a collision mesh by the Torque engine.
When a Torque mission is started, the following steps occur:
- On the server, Torque executes art/datablocks/datablockExec.cs, which in turn executes art/datablocks/myShape.cs
- Executing art/datablocks/myShape.cs causes the MyShapeData datablock to attempt to load the DTS file
- Before loading the DTS file, Torque executes art/shapes/myShape/myShape.cs, which creates the TSShapeConstructor object
- After loading the DTS file, Torque executes MyShapeDts::onLoad, which adds the collision detail level to the shape
- The StaticShape object can now be added to the scene (it will appear in the world editor (in the "Misc" category under the Library/Scripted tab)
Example 2: Adding a Mesh From an Existing DTS File
The image below shows a boulder.dts shape in the Torque Show Tool Pro (TSTPro). The circled items indicate the geometry and material that will be copied into a different shape using TSShapeConstructor.
The following shows how to include the boulder1 mesh in another shape:
singleton TSShapeConstructor( TestShapeDts ) { baseShape = "~/art/shapes/rocks/rock1.dts"; }; function TestShapeDts::onLoad( %this ) { %this.addMesh( "test128", "~/art/shapes/rocks/boulder.dts", "boulder1" ); %this.dumpShape(); }
The output of the dumpShape command is shown below:
Shape Hierarchy: Details: detail128, Subtree 0, objectDetail 0, size 128 detail2, Subtree 0, objectDetail 1, size 2 collision-1, Subtree 0, objectDetail 2, size -1 Subtrees: Subtree 0 Rock2 --> Object Rock with following details: 2 --> Object test with following details: 128 col-1 --> Object col with following details: -1 Sequences: %Material list: material #0: 'rock2'. material #1: 'MossyRock02'.
Note that the new detail ("detail128"), object ("test") and material ("MossyRock02") have been added to the normal rock1.dts shape.
Example 3: Auto-loading animations
Instead of manually specifying all of the animations to load, it's easy to write some TorqueScript that will scan a folder for any matching animations and add them to the shape automatically. Imagine that we have the following shape (DTS) and sequence (DSQ) files:
- art/shapes/actors/ForgeSoldier/ForgeSoldier.dts
- art/shapes/actors/animations/player_root.dsq
- art/shapes/actors/animations/player_run.dsq
- art/shapes/actors/animations/player_back.dsq
- art/shapes/actors/animations/player_side.dsq
- art/shapes/actors/animations/player_death0.dsq
The following script will scan the animations folder and add the sequences to the shape.
singleton TSShapeConstructor( ForgeSoldierDts ) { baseShape = "~/art/shapes/actors/ForgeSoldier/ForgeSolder.dts"; }; function ForgeSoldierDts::onLoad( %this ) { AddAnimations( %this ); } function AddAnimations( %shape ) { // Scan for all player_*.dsq files and add the animations to the shape. // Sequence names are taken from the base name of the dsq file. eg. // player_run.dsq would add a sequence called 'run'. %filePatterns = "art/shapes/actors/animations/player_*.dsq"; %fullPath = findFirstFileMultiExpr( %filePatterns ); while ( %fullPath !$= "" ) { // add this animation to the shape %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); %seq_name = strreplace( filebase( %fullPath ), "player_", "" ); %shape.addSequence( %fullpath, %seq_name ); %fullPath = findNextFileMultiExpr( %filePatterns ); } }
Example 4: Splitting COLLADA animations
Many COLLADA exporters do not support the <animation_clip> element, meaning that animated models imported into Torque appear to have only a single sequence containing all of the animations. TSShapeConstructor can be used to split this combined animation into individual sequences. This is most easily done using the Shape Editor tool, but can also be done manually as follows:
singleton TSShapeConstructor( PlayerModelDts ) { baseShape = "~/art/shapes/collada/myPlayer.dae"; }; function PlayerModelDts::onLoad( %this ) { // Split animations from combined "ambient" sequence %this.addSequence( "ambient", "root", 0, 15 ); %this.addSequence( "ambient", "run", 16, 40 ); %this.addSequence( "ambient", "back", 41, 55 ); %this.addSequence( "ambient", "side", 56, 70 ); %this.addSequence( "ambient", "death0", 80, 120 ); // Remove combined "ambient" sequence => we don't need it anymore %this.removeSequence( "ambient" ); }
Example 5: LOD using separate files
In the past, using LOD required the artist to export all detail levels into a single DTS file. Using TSShapeConstructor, we can combine separate model files together. In fact, we can even use the folder-scanning approach from Example 3 to automatically construct the shape detail levels using all of the model files in the folder!
Note that the detail level models must contain the same object name, and for skinned models, the skin must be applied to the same skeleton for this script to work.
Imagine that we have the following shape (DAE) files:
- art/shapes/actors/soldier/soldier.dae (the base model, highest detail level size=1024)
- art/shapes/actors/soldier/soldier_512.dae
- art/shapes/actors/soldier/soldier_256.dae
- art/shapes/actors/soldier/soldier_64.dae
singleton TSShapeConstructor( SoldierDae ) { baseShape = "~/art/shapes/actors/soldier.dae"; }; function SoldierDae::onLoad( %this ) { %objName = %this.getObjectName( 0 ); AddDetails( %this, %objName ); } // Scan for all DAE files in the folder with the same base name, and add the // skinned mesh from that file to the input shape. The size of the detail level // is taken from the end of the filename. eg. soldier_30.dae will add detail // level 30 to the shape. // Note that this function can be in a different script so it can be shared by // multiple TSShapeConstructor objects... function AddDetails( %shape, %objName ) { // Determine the base name of the input file. eg. the basename of // soldier.dae is 'soldier'. %inputBase = fileBase( %shape.baseShape ); %filePatterns = filePath( %shape.baseShape ) @ "/" @ %inputBase @ "_*.dae"; %fullPath = findFirstFileMultiExpr( %filePatterns ); while (%fullPath !$= "") { %fullPath = makeRelativePath( %fullPath, getMainDotCSDir() ); // Determine the detail size, then add the new mesh (assumes exported with size = 2) %size = strreplace( fileBase( %fullPath ), %inputBase @ "_", "" ); %shape.addMesh( %objName SPC %size, %fullPath, %objName SPC "2" ); %fullPath = findNextFileMultiExpr( %filePatterns ); } }
Example 6: Add lights to the scene
Although most often used to modify a shape before it is used, TSShapeConstructor can also be used as a general purpose interface to a 3D shape. For example, a 3D modeling package could be used to layout positions for lights in the scene. On import, the shape hierarchy might look like this:
base01 +-start01 +-Lights +-lightA +-lightB +-lightC ...
The following code demonstrates how to create a TSShapeConstructor object on-demand in order to access the 3D shape data. This example adds lights to the current scene at position of the lightX nodes in the shape:
function AddLights( %obj ) { // Get a TSShapeConstructor for this object (use the ShapeEditor // utility functions to create one if it does not already exist). %shapePath = ShapeEditor.getObjectShapeFile( %obj ); %shape = ShapeEditor.findConstructor( %shapePath ); if ( !isObject( %shape ) ) %shape = ShapeEditor.createConstructor( %shapePath ); if ( !isObject( %shape ) ) { echo( "Failed to create TSShapeConstructor for " @ %obj.getId() ); return; } %objTransform = %obj.getTransform(); %lightsGroup = "Lights"; %count = %shape.getNodeChildCount( %lightsGroup ); for ( %i = 0; %i < %count; %i++ ) { // get node transform in object space, then transform to world space %child = %shape.getNodeChildName( %lightsGroup, %i ); %txfm = %shape.getNodeTransform( %child, true ); %txfm = MatrixMultiply( %objTransform, %txfm ); // create a new light at the object node %light = new PointLight() { position = getWords( %txfm, 0, 2 ); rotation = getWords( %txfm, 3, 6 ); }; MissionGroup.add( %light ); } }
The original shape can be placed anywhere in the scene, then AddLights is called to create and place a PointLight at each node.
Example 7: Rigid-body Player Character
Using the addNode and addMesh functions, it is possible to create a rigid-body (ie. non-skinned) player model compatible with the default animations, completely from TorqueScript!
The default player skeleton node transforms were obtained by adding the following code to the TSShapeConstructor onLoad function for a shape that already contained the default skeleton:
%count = %this.getNodeCount(); for ( %i = 0; %i < %count; %i++ ) { %name = %this.getNodeName( %i ); echo( "%shape.addNode(\"" @ %name @ "\", \"" @ %this.getNodeParentName( %name ) @ "\", \"" @ %this.getNodeTransform( %name ) @ "\");" ); }
The contents of the console can then be copied and pasted into a new script. The script below shows the player model creation process: first pick a dummy dts file (rock1.dts in this case), and delete its existing nodes and meshes. Then create the default player skeleton. Finally, some box meshes are added at certain nodes to build up a rigid-body player character.
// Create the default Torque skeleton (compatible with the default player animations) function CreateDefaultSkeleton( %shape ) { %shape.addNode( "Bip01 Pelvis", "", "-8.10647e-005 8.34974e-006 1.28118 0.00147092 0.999914 0.000312013 1.50833" ); %shape.addNode( "Bip01 Spine", "Bip01 Pelvis", "0.117738 -0.000117005 0.00695224 0.995531 0 0.054662 0.178899" ); %shape.addNode( "Bip01 Spine1", "Bip01 Spine", "0.149188 -0.000154936 5.87594e-006 0.158383 0.207314 0.965104 0.285376" ); %shape.addNode( "Bip01 Spine2", "Bip01 Spine1", "0.202462 -0.000162536 2.93078e-005 0.731516 -0.35723 -0.579706 0.251143" ); %shape.addNode( "Bip01 Neck", "Bip01 Spine2", "0.209867 -4.86846e-005 -2.05922e-005 -0.926274 0.0899337 -0.365008 0.431595" ); %shape.addNode( "Bip01 Head", "Bip01 Neck", "0.067264 -6.98505e-009 -6.66524e-009 -0.139433 0.872649 -0.450268 0.089769" ); %shape.addNode( "Eye", "Bip01 Head", "0.180021 0.33282 -0.00125568 -0.0139777 -0.999387 0.030751 1.57784" ); %shape.addNode( "Bip01 L Clavicle", "Bip01 Neck", "0.0059334 0.0332864 0.0795624 -0.632128 -0.230228 -0.739819 2.58923" ); %shape.addNode( "Bip01 L UpperArm", "Bip01 L Clavicle", "0.358891 -1.27006e-008 1.34618e-007 0.300944 -0.93298 0.197112 1.51847" ); %shape.addNode( "Bip01 L Forearm", "Bip01 L UpperArm", "0.395474 -1.37648e-008 1.96789e-008 0 0 0.999871 0.850149" ); %shape.addNode( "Bip01 L Hand", "Bip01 L Forearm", "0.363508 3.95569e-008 3.80099e-008 -0.975012 -0.0676349 0.211535 3.8945" ); %shape.addNode( "Bip01 R Clavicle", "Bip01 Neck", "-0.00593357 -0.0331793 -0.0795624 0.631473 -0.0957054 -0.769459 3.0916" ); %shape.addNode( "Bip01 R UpperArm", "Bip01 R Clavicle", "0.358891 -1.02138e-008 1.01681e-007 0.594451 0.803854 -0.017401 1.47305" ); %shape.addNode( "Bip01 R Forearm", "Bip01 R UpperArm", "0.395474 6.19864e-008 1.31302e-008 0 0 0.999951 1.88239" ); %shape.addNode( "Bip01 R Hand", "Bip01 R Forearm", "0.363508 1.03579e-008 -1.18848e-008 -0.976003 -0.105148 0.190568 1.71108" ); %shape.addNode( "mount0", "Bip01 R Hand", "0.192386 0.0479768 0.000897807 0.0616579 0.0736096 0.995312 1.76131" ); %shape.addNode( "mount2", "Bip01 Spine2", "0.101603 -0.255502 0.00682753 0.0431623 -0.998124 -0.0431623 1.57267" ); %shape.addNode( "mount1", "Bip01 Spine2", "0.101603 -0.255502 0.00682756 0.0431623 -0.998124 -0.0431623 1.57267" ); %shape.addNode( "Bip01 L Thigh", "Bip01 Spine", "-0.117582 -0.0342993 0.1847 -0.227865 -0.966002 -0.121932 3.27836" ); %shape.addNode( "Bip01 L Calf", "Bip01 L Thigh", "0.567764 2.88694e-008 -2.61884e-009 0 0 0.999795 0.784881" ); %shape.addNode( "Bip01 L Foot", "Bip01 L Calf", "0.659264 6.37417e-009 5.70856e-009 -0.0798252 0.398941 -0.913186 0.331842" ); %shape.addNode( "Ski0", "Bip01 L Foot", "0.587469 -0.0426512 -0.0990439 0.750521 0.554827 0.358877 1.9778" ); %shape.addNode( "Bip01 R Thigh", "Bip01 Spine", "-0.117896 0.0347 -0.198562 -0.134559 -0.982239 0.130533 2.9039" ); %shape.addNode( "Bip01 R Calf", "Bip01 R Thigh", "0.567764 8.48371e-010 1.88575e-009 0 0 0.999915 0.836729" ); %shape.addNode( "Bip01 R Foot", "Bip01 R Calf", "0.659264 -3.34983e-008 -2.20877e-008 0.0784375 -0.241304 -0.967069 0.567876" ); %shape.addNode( "Ski1", "Bip01 R Foot", "0.600815 -0.0369749 0.0998079 -0.352371 -0.698146 -0.62318 3.91937" ); %shape.addNode( "Unlink", "", "-0.00586435 -0.000234549 0.056661 -0.579417 -0.577691 -0.574872 2.09521" ); %shape.addNode( "Cam", "Unlink", "0.237214 2.06536 -0.00742381 0.999942 -0.00266823 -0.00189359 1.57655" ); } // Create a new box mesh at the specified node function CreateBoxObject( %shape, %name, %node, %size, %offset ) { if ( %offset $= "" ) %offset = "0 0 0"; %shape.addPrimitive( %name @ "2", "box", %size, %offset SPC "0 0 1 0", %node ); } // Create a simple (rigid) player model using boxes for body parts function CreateRigidPlayer( %shape ) { CreateBoxObject( %shape, "head", "Eye", "0.2 0.2 0.3" ); CreateBoxObject( %shape, "upper_torso", "Bip01 Spine2", "0.3 0.2 0.4" ); CreateBoxObject( %shape, "lower_torso", "Bip01 Spine", "0.3 0.2 0.35" ); CreateBoxObject( %shape, "left_thigh", "Bip01 L Thigh", "0.5 0.2 0.2", "0.25 0 0" ); CreateBoxObject( %shape, "left_leg", "Bip01 L Calf", "0.4 0.2 0.2", "0.25 0 0" ); CreateBoxObject( %shape, "left_foot", "Bip01 L Foot", "0.2 0.2 0.2" ); CreateBoxObject( %shape, "right_thigh", "Bip01 R Thigh", "0.5 0.2 0.2", "0.25 0 0" ); CreateBoxObject( %shape, "right_leg", "Bip01 R Calf", "0.4 0.2 0.2", "0.25 0 0" ); CreateBoxObject( %shape, "right_foot", "Bip01 R Foot", "0.2 0.2 0.2" ); CreateBoxObject( %shape, "left_upper_arm", "Bip01 L UpperArm", "0.3 0.15 0.15", "0.15 0 0" ); CreateBoxObject( %shape, "left_forearm", "Bip01 L Forearm", "0.2 0.15 0.15", "0.1 0 0" ); CreateBoxObject( %shape, "left_hand", "Bip01 L Hand", "0.15 0.15 0.15" ); CreateBoxObject( %shape, "right_upper_arm", "Bip01 R UpperArm", "0.3 0.15 0.15", "0.15 0 0" ); CreateBoxObject( %shape, "right_forearm", "Bip01 R Forearm", "0.2 0.15 0.15", "0.1 0 0" ); CreateBoxObject( %shape, "right_hand", "Bip01 R Hand", "0.15 0.15 0.15" ); // create collision mesh %shape.addCollisionDetail( -1, "box", "bounds" ); } singleton TSShapeConstructor( TestModelDts ) { baseShape = "~/art/shapes/rocks/rock1.dts"; }; function TestModelDts::onLoad( %this ) { // remove the existing nodes and geometry so we start with a blank shape %count = %this.getObjectCount(); for ( %i = %count-1; %i >= 0; %i-- ) %this.removeObject( %this.getObjectName( %i ) ); %count = %this.getNodeCount(); for ( %i = %count-1; %i >= 0; %i-- ) %this.removeNode( %this.getNodeName( %i ) ); // create the player skeleton and rigid body parts CreateDefaultSkeleton( %this ); CreateRigidPlayer( %this ); // now load the default sequences %this.addSequence( "~/art/shapes/actors/animations/player_root.dsq", "root" ); %this.addSequence( "~/art/shapes/actors/animations/player_forward.dsq", "run" ); %this.dumpShape(); } // The player model definition singleton PlayerData( TestModelData : DefaultPlayerData ) { renderFirstPerson = false; emap = true; //className = Armor; shapeFile = "~/art/shapes/rocks/rock1.dts"; }; PlayerDatasGroup.add( TestModelData );
This produces the following shape:
Shape Hierarchy: Details: detail2, Subtree 0, objectDetail 0, size 2 collision-1, Subtree 0, objectDetail 1, size -1 Subtrees: Subtree 0 Bip01 Pelvis --> Object col with following details: -1 Bip01 Spine --> Object lower_torso with following details: 2 Bip01 Spine1 Bip01 Spine2 --> Object upper_torso with following details: 2 Bip01 Neck Bip01 Head Eye --> Object head with following details: 2 Bip01 L Clavicle Bip01 L UpperArm --> Object left_upper_arm with following details: 2 Bip01 L Forearm --> Object left_forearm with following details: 2 Bip01 L Hand --> Object left_Hand with following details: 2 Bip01 R Clavicle Bip01 R UpperArm --> Object right_upper_arm with following details: 2 Bip01 R Forearm --> Object right_forearm with following details: 2 Bip01 R Hand --> Object right_hand with following details: 2 Mount0 Mount2 Mount1 Bip01 L Thigh --> Object left_thigh with following details: 2 Bip01 L Calf --> Object left_leg with following details: 2 Bip01 L Foot --> Object left_foot with following details: 2 Ski0 Bip01 R Thigh --> Object right_thigh with following details: 2 Bip01 R Calf --> Object right_leg with following details: 2 Bip01 R Foot --> Object right_foot with following details: 2 Ski1 Unlink Cam Sequences: 0: %Root (cyclic) 1: run (cyclic)
Member Function Documentation
bool TSShapeConstructor::addCollisionDetail | ( | int | size, | |
string | type, | |||
string | target, | |||
int | depth = 4 , |
|||
float | merge = 30 , |
|||
float | concavity = 30 , |
|||
int | maxVerts = 32 , |
|||
float | boxMaxError = 0 , |
|||
float | sphereMaxError = 0 , |
|||
float | capsuleMaxError = 0 | |||
) |
Autofit a mesh primitive or set of convex hulls to the shape geometry. Hulls may optionally be converted to boxes, spheres and/or capsules based on their volume.
- Parameters:
-
size size for this detail level type one of: box, sphere, capsule, 10-dop x, 10-dop y, 10-dop z, 18-dop, 26-dop, convex hulls. See the Shape Editor documentation for more details about these types. target geometry to fit collision mesh(es) to; either "bounds" (for the whole shape), or the name of an object in the shape depth maximum split recursion depth (hulls only) merge volume % threshold used to merge hulls together (hulls only) concavity volume % threshold used to detect concavity (hulls only) maxVerts maximum number of vertices per hull (hulls only) boxMaxError max % volume difference for a hull to be converted to a box (hulls only) sphereMaxError max % volume difference for a hull to be converted to a sphere (hulls only) capsuleMaxError max % volume difference for a hull to be converted to a capsule (hulls only)
- Returns:
- true if successful, false otherwise
- Example:
%this.addCollisionDetail( -1, "box", "bounds" ); %this.addCollisionDetail( -1, "convex hulls", "bounds", 4, 30, 30, 32, 0, 0, 0 ); %this.addCollisionDetail( -1, "convex hulls", "bounds", 4, 30, 30, 32, 50, 50, 50 );
int TSShapeConstructor::addImposter | ( | int | size, | |
int | equatorSteps, | |||
int | polarSteps, | |||
int | dl, | |||
int | dim, | |||
bool | includePoles, | |||
float | polarAngle | |||
) |
Add (or edit) an imposter detail level to the shape.
If the shape already contains an imposter detail level, this command will simply change the imposter settings
- Parameters:
-
size size of the imposter detail level equatorSteps defines the number of snapshots to take around the equator. Imagine the object being rotated around the vertical axis, then a snapshot taken at regularly spaced intervals. polarSteps defines the number of snapshots taken between the poles (top and bottom), at each equator step. eg. At each equator snapshot, snapshots are taken at regular intervals between the poles. dl the detail level to use when generating the snapshots. Note that this is an array index rather than a detail size. So if an object has detail sizes of: 200, 150, and 40, then setting dl to 1 will generate the snapshots using detail size 150. dim defines the size of the imposter images in pixels. The larger the number, the more detailed the billboard will be. includePoles flag indicating whether to include the "pole" snapshots. ie. the views from the top and bottom of the object. polar_angle if pole snapshots are active (includePoles is true), this parameter defines the camera angle (in degrees) within which to render the pole snapshot. eg. if polar_angle is set to 25 degrees, then the snapshot taken at the pole (looking directly down or up at the object) will be rendered when the camera is within 25 degrees of the pole.
- Returns:
- true if successful, false otherwise
- Example:
%this.addImposter( 2, 4, 0, 0, 64, false, 0 ); %this.addImposter( 2, 4, 2, 0, 64, true, 10 ); // this command would edit the existing imposter detail level
bool TSShapeConstructor::addMesh | ( | string | meshName, | |
string | srcShape, | |||
string | srcMesh | |||
) |
Add geometry from another DTS or DAE shape file into this shape.
Any materials required by the source mesh are also copied into this shape.
- Parameters:
-
meshName full name (object name + detail size) of the new mesh. If no detail size is present at the end of the name, a value of 2 is used.
An underscore before the number at the end of the name will be interpreted as a negative sign. eg. "MyMesh_4" will be interpreted as "MyMesh-4".srcShape name of a shape file (DTS or DAE) that contains the mesh srcMesh the full name (object name + detail size) of the mesh to copy from the DTS/DAE file into this shape
- Returns:
- true if successful, false otherwise
- Example:
bool TSShapeConstructor::addNode | ( | string | name, | |
string | parentName, | |||
TransformF | txfm = TransformF::Identity , |
|||
bool | isWorld = false | |||
) |
Add a new node.
- Parameters:
-
name name for the new node (must not already exist) parentName name of an existing node to be the parent of the new node. If empty (""), the new node will be at the root level of the node hierarchy. txfm (optional) transform string of the form: "pos.x pos.y pos.z rot.x rot.y rot.z rot.angle" isworld (optional) flag to set the local-to-parent or the global transform. If false, or not specified, the position and orientation are treated as relative to the node's parent.
- Returns:
- true if successful, false otherwise
- Example:
bool TSShapeConstructor::addPrimitive | ( | string | meshName, | |
string | type, | |||
string | params, | |||
TransformF | txfm, | |||
string | nodeName | |||
) |
Add a new mesh primitive to the shape.
- Parameters:
-
meshName full name (object name + detail size) of the new mesh. If no detail size is present at the end of the name, a value of 2 is used.
An underscore before the number at the end of the name will be interpreted as a negative sign. eg. "MyMesh_4" will be interpreted as "MyMesh-4".type one of: "box", "sphere", "capsule" params mesh primitive parameters: - for box: "size_x size_y size_z"
- for sphere: "radius"
- for capsule: "height radius"
txfm local transform offset from the node for this mesh nodeName name of the node to attach the new mesh to (will change the object's node if adding a new mesh to an existing object)
- Returns:
- true if successful, false otherwise
- Example:
bool TSShapeConstructor::addSequence | ( | string | source, | |
string | name, | |||
int | start = 0 , |
|||
int | end = -1 , |
|||
bool | padRot = true , |
|||
bool | padTrans = false | |||
) |
Add a new sequence to the shape.
- Parameters:
-
source the name of an existing sequence, or the name of a DTS or DAE shape or DSQ sequence file. When the shape file contains more than one sequence, the desired sequence can be specified by appending the name to the end of the shape file. eg. "myShape.dts run" would select the "run" sequence from the "myShape.dts" file. name name of the new sequence start (optional) first frame to copy. Defaults to 0, the first frame in the sequence. end (optional) last frame to copy. Defaults to -1, the last frame in the sequence. padRot (optional) copy root-pose rotation keys for non-animated nodes. This is useful if the source sequence data has a different root-pose to the target shape, such as if one character was in the T pose, and the other had arms at the side. Normally only nodes that are actually rotated by the source sequence have keyframes added, but setting this flag will also add keyframes for nodes that are not animated, but have a different root-pose rotation to the target shape root pose. padTrans (optional) copy root-pose translation keys for non-animated nodes. This is useful if the source sequence data has a different root-pose to the target shape, such as if one character was in the T pose, and the other had arms at the side. Normally only nodes that are actually moved by the source sequence have keyframes added, but setting this flag will also add keyframes for nodes that are not animated, but have a different root-pose position to the target shape root pose.
- Returns:
- true if successful, false otherwise
- Example:
%this.addSequence( "./testShape.dts ambient", "ambient" ); %this.addSequence( "./myPlayer.dae run", "run" ); %this.addSequence( "./player_look.dsq", "look", 0, -1 ); // start to end %this.addSequence( "walk", "walk_shortA", 0, 4 ); // start to frame 4 %this.addSequence( "walk", "walk_shortB", 4, -1 ); // frame 4 to end
bool TSShapeConstructor::addTrigger | ( | string | name, | |
int | keyframe, | |||
int | state | |||
) |
Add a new trigger to the sequence.
- Parameters:
-
name name of the sequence to modify keyframe keyframe of the new trigger state of the new trigger
- Returns:
- true if successful, false otherwise
- Example:
%this.addTrigger( "walk", 3, 1 ); %this.addTrigger( "walk", 5, -1 );
void TSShapeConstructor::dumpShape | ( | string | filename = "" |
) |
Box3F TSShapeConstructor::getBounds | ( | ) |
Get the bounding box for the shape.
- Returns:
- Bounding box "minX minY minZ maxX maxY maxZ"
int TSShapeConstructor::getDetailLevelCount | ( | ) |
Get the total number of detail levels in the shape.
- Returns:
- the number of detail levels in the shape
int TSShapeConstructor::getDetailLevelIndex | ( | int | size | ) |
Get the index of the detail level with a given size.
- Parameters:
-
size size of the detail level to lookup
- Returns:
- index of the detail level with the desired size, or -1 if no such detail exists
- Example:
if ( %this.getDetailLevelSize( 32 ) == -1 ) echo( "Error: This shape does not have a detail level at size 32" );
string TSShapeConstructor::getDetailLevelName | ( | int | index | ) |
Get the name of the indexed detail level.
- Parameters:
-
index detail level index (valid range is 0 - getDetailLevelCount()-1)
- Returns:
- the detail level name
- Example:
// print the names of all detail levels in the shape %count = %this.getDetailLevelCount(); for ( %i = 0; %i < %count; %i++ ) echo( %i SPC %this.getDetailLevelName( %i ) );
int TSShapeConstructor::getDetailLevelSize | ( | int | index | ) |
Get the size of the indexed detail level.
- Parameters:
-
index detail level index (valid range is 0 - getDetailLevelCount()-1)
- Returns:
- the detail level size
- Example:
// print the sizes of all detail levels in the shape %count = %this.getDetailLevelCount(); for ( %i = 0; %i < %count; %i++ ) echo( "Detail" @ %i @ " has size " @ %this.getDetailLevelSize( %i ) );
int TSShapeConstructor::getImposterDetailLevel | ( | ) |
Get the index of the imposter (auto-billboard) detail level (if any).
- Returns:
- imposter detail level index, or -1 if the shape does not use imposters.
string TSShapeConstructor::getImposterSettings | ( | int | index | ) |
Get the settings used to generate imposters for the indexed detail level.
- Parameters:
-
index index of the detail level to query (does not need to be an imposter detail level
- Returns:
- string of the form: "valid eqSteps pSteps dl dim poles angle", where:
- valid
- 1 if this detail level generates imposters, 0 otherwise
- eqSteps
- number of steps around the equator
- pSteps
- number of steps between the poles
- dl
- index of the detail level used to generate imposters
- dim
- size (in pixels) of each imposter image
- poles
- 1 to include pole images, 0 otherwise
- angle
- angle at which to display pole images
- Example:
// print the imposter detail level settings %index = %this.getImposterDetailLevel(); if ( %index != -1 ) echo( "Imposter settings: " @ %this.getImposterSettings( %index ) );
int TSShapeConstructor::getMeshCount | ( | string | name | ) |
Get the number of meshes (detail levels) for the specified object.
- Parameters:
-
name name of the object to query
- Returns:
- the number of meshes for this object.
- Example:
%count = %this.getMeshCount( "SimpleShape" );
string TSShapeConstructor::getMeshMaterial | ( | string | name | ) |
Get the name of the material attached to a mesh. Note that only the first material used by the mesh is returned.
- Parameters:
-
name full name (object name + detail size) of the mesh to query
- Returns:
- name of the material attached to the mesh (suitable for use with the Material mapTo field)
- Example:
echo( "Mesh material is " @ %this.sgetMeshMaterial( "SimpleShape128" ) );
string TSShapeConstructor::getMeshName | ( | string | name, | |
int | index | |||
) |
Get the name of the indexed mesh (detail level) for the specified object.
- Parameters:
-
name name of the object to query index index of the mesh (valid range is 0 - getMeshCount()-1)
- Returns:
- the mesh name.
- Example:
// print the names of all meshes in the shape %objCount = %this.getObjectCount(); for ( %i = 0; %i < %objCount; %i++ ) { %objName = %this.getObjectName( %i ); %meshCount = %this.getMeshCount( %objName ); for ( %j = 0; %j < %meshCount; %j++ ) echo( %this.getMeshName( %objName, %j ) ); }
int TSShapeConstructor::getMeshSize | ( | string | name, | |
int | index | |||
) |
Get the detail level size of the indexed mesh for the specified object.
- Parameters:
-
name name of the object to query index index of the mesh (valid range is 0 - getMeshCount()-1)
- Returns:
- the mesh detail level size.
- Example:
// print sizes for all detail levels of this object %objName = "trunk"; %count = %this.getMeshCount( %objName ); for ( %i = 0; %i < %count; %i++ ) echo( %this.getMeshSize( %objName, %i ) );
string TSShapeConstructor::getMeshType | ( | string | name | ) |
Get the display type of the mesh.
- Parameters:
-
name name of the mesh to query
- Returns:
- the string returned is one of:
- normal
- a normal 3D mesh
- billboard
- a mesh that always faces the camera
- billboardzaxis
- a mesh that always faces the camera in the Z-axis
- Example:
echo( "Mesh type is " @ %this.getMeshType( "SimpleShape128" ) );
int TSShapeConstructor::getNodeChildCount | ( | string | name | ) |
Get the number of children of this node.
- Parameters:
-
name name of the node to query.
- Returns:
- the number of child nodes.
- Example:
%count = %this.getNodeChildCount( "Bip01 Pelvis" );
string TSShapeConstructor::getNodeChildName | ( | string | name, | |
int | index | |||
) |
Get the name of the indexed child node.
- Parameters:
-
name name of the parent node to query. index index of the child node (valid range is 0 - getNodeChildName()-1).
- Returns:
- the name of the indexed child node.
- Example:
function dumpNode( %shape, %name, %indent ) { echo( %indent @ %name ); %count = %shape.getNodeChildCount( %name ); for ( %i = 0; %i < %count; %i++ ) dumpNode( %shape, %shape.getNodeChildName( %name, %i ), %indent @ " " ); } function dumpShape( %shape ) { // recursively dump node hierarchy %count = %shape.getNodeCount(); for ( %i = 0; %i < %count; %i++ ) { // dump top level nodes %name = %shape.getNodeName( %i ); if ( %shape.getNodeParentName( %name ) $= ) dumpNode( %shape, %name, "" ); } }
int TSShapeConstructor::getNodeCount | ( | ) |
Get the total number of nodes in the shape.
- Returns:
- the number of nodes in the shape.
- Example:
%count = %this.getNodeCount();
int TSShapeConstructor::getNodeIndex | ( | string | name | ) |
Get the index of the node.
- Parameters:
-
name name of the node to lookup.
- Returns:
- the index of the named node, or -1 if no such node exists.
- Example:
// get the index of Bip01 Pelvis node in the shape %index = %this.getNodeIndex( "Bip01 Pelvis" );
string TSShapeConstructor::getNodeName | ( | int | index | ) |
Get the name of the indexed node.
- Parameters:
-
index index of the node to lookup (valid range is 0 - getNodeCount()-1).
- Returns:
- the name of the indexed node, or "" if no such node exists.
- Example:
// print the names of all the nodes in the shape %count = %this.getNodeCount(); for (%i = 0; %i < %count; %i++) echo(%i SPC %this.getNodeName(%i));
int TSShapeConstructor::getNodeObjectCount | ( | string | name | ) |
Get the number of geometry objects attached to this node.
- Parameters:
-
name name of the node to query.
- Returns:
- the number of attached objects.
- Example:
%count = %this.getNodeObjectCount( "Bip01 Head" );
string TSShapeConstructor::getNodeObjectName | ( | string | name, | |
int | index | |||
) |
Get the name of the indexed object.
- Parameters:
-
name name of the node to query. index index of the object (valid range is 0 - getNodeObjectCount()-1).
- Returns:
- the name of the indexed object.
- Example:
// print the names of all objects attached to the node %count = %this.getNodeObjectCount( "Bip01 Head" ); for ( %i = 0; %i < %count; %i++ ) echo( %this.getNodeObjectName( "Bip01 Head", %i ) );
string TSShapeConstructor::getNodeParentName | ( | string | name | ) |
Get the name of the node's parent. If the node has no parent (ie. it is at the root level), return an empty string.
- Parameters:
-
name name of the node to query.
- Returns:
- the name of the node's parent, or "" if the node is at the root level
- Example:
echo( "Bip01 Pelvis parent = " @ %this.getNodeParentName( "Bip01 Pelvis ") );
TransformF TSShapeConstructor::getNodeTransform | ( | string | name, | |
bool | isWorld = false | |||
) |
Get the base (ie. not animated) transform of a node.
- Parameters:
-
name name of the node to query. isWorld true to get the global transform, false (or omitted) to get the local-to-parent transform.
- Returns:
- the node transform in the form "pos.x pos.y pos.z rot.x rot.y rot.z rot.angle".
- Example:
%ret = %this.getNodeTransform( "mount0" ); %this.setNodeTransform( "mount4", %ret );
int TSShapeConstructor::getObjectCount | ( | ) |
Get the total number of objects in the shape.
- Returns:
- the number of objects in the shape.
- Example:
%count = %this.getObjectCount();
int TSShapeConstructor::getObjectIndex | ( | string | name | ) |
Get the index of the first object with the given name.
- Parameters:
-
name name of the object to get.
- Returns:
- the index of the named object.
- Example:
%index = %this.getObjectIndex( "Head" );
string TSShapeConstructor::getObjectName | ( | int | index | ) |
Get the name of the indexed object.
- Parameters:
-
index index of the object to get (valid range is 0 - getObjectCount()-1).
- Returns:
- the name of the indexed object.
- Example:
// print the names of all objects in the shape %count = %this.getObjectCount(); for ( %i = 0; %i < %count; %i++ ) echo( %i SPC %this.getObjectName( %i ) );
string TSShapeConstructor::getObjectNode | ( | string | name | ) |
Get the name of the node this object is attached to.
- Parameters:
-
name name of the object to get.
- Returns:
- the name of the attached node, or an empty string if this object is not attached to a node (usually the case for skinned meshes).
- Example:
echo( "Hand is attached to " @ %this.getObjectNode( "Hand" ) );
string TSShapeConstructor::getSequenceBlend | ( | string | name | ) |
Get information about blended sequences.
- Parameters:
-
name name of the sequence to query
- Returns:
- TAB delimited string of the form: "isBlend blendSeq blendFrame", where:
- blend_flag
- a boolean flag indicating whether this sequence is a blend
- blend_seq_name
- the name of the sequence that contains the reference frame (empty for blend sequences embedded in DTS files)
- blend_seq_frame
- the blend reference frame (empty for blend sequences embedded in DTS files)
- Note:
- Note that only sequences set to be blends using the setSequenceBlend command will contain the blendSeq and blendFrame information.
- Example:
%blendData = %this.getSequenceBlend( "look" ); if ( getField( %blendData, 0 ) ) echo( "look is a blend, reference: " @ getField( %blendData, 1 ) );
int TSShapeConstructor::getSequenceCount | ( | ) |
Get the total number of sequences in the shape.
- Returns:
- the number of sequences in the shape
bool TSShapeConstructor::getSequenceCyclic | ( | string | name | ) |
Check if this sequence is cyclic (looping).
- Parameters:
-
name name of the sequence to query
- Returns:
- true if this sequence is cyclic, false if not
- Example:
if ( !%this.getSequenceCyclic( "ambient" ) ) error( "ambient sequence is not cyclic!" );
int TSShapeConstructor::getSequenceFrameCount | ( | string | name | ) |
Get the number of keyframes in the sequence.
- Parameters:
-
name name of the sequence to query
- Returns:
- number of keyframes in the sequence
- Example:
echo( "Run has " @ %this.getSequenceFrameCount( "run" ) @ " keyframes" );
string TSShapeConstructor::getSequenceGroundSpeed | ( | string | name | ) |
Get the ground speed of the sequence.
- Note:
- Note that only the first 2 ground frames of the sequence are examined; the speed is assumed to be constant throughout the sequence.
- Parameters:
-
name name of the sequence to query
- Returns:
- string of the form: "trans.x trans.y trans.z rot.x rot.y rot.z"
- Example:
%speed = VectorLen( getWords( %this.getSequenceGroundSpeed( "run" ), 0, 2 ) ); echo( "Run moves at " @ %speed @ " units per frame" );
int TSShapeConstructor::getSequenceIndex | ( | string | name | ) |
Find the index of the sequence with the given name.
- Parameters:
-
name name of the sequence to lookup
- Returns:
- index of the sequence with matching name, or -1 if not found
- Example:
// Check if a given sequence exists in the shape if ( %this.getSequenceIndex( "walk" ) == -1 ) echo( "Could not find 'walk' sequence" );
string TSShapeConstructor::getSequenceName | ( | int | index | ) |
Get the name of the indexed sequence.
- Parameters:
-
index index of the sequence to query (valid range is 0 - getSequenceCount()-1)
- Returns:
- the name of the sequence
- Example:
// print the name of all sequences in the shape %count = %this.getSequenceCount(); for ( %i = 0; %i < %count; %i++ ) echo( %i SPC %this.getSequenceName( %i ) );
float TSShapeConstructor::getSequencePriority | ( | string | name | ) |
Get the priority setting of the sequence.
- Parameters:
-
name name of the sequence to query
- Returns:
- priority value of the sequence
string TSShapeConstructor::getSequenceSource | ( | string | name | ) |
Get information about where the sequence data came from.
For example, whether it was loaded from an external DSQ file.
- Parameters:
-
name name of the sequence to query
- Returns:
- TAB delimited string of the form: "from reserved start end total", where:
- from
- the source of the animation data, such as the path to a DSQ file, or the name of an existing sequence in the shape. This field will be empty for sequences already embedded in the DTS or DAE file.
- reserved
- reserved value
- start
- the first frame in the source sequence used to create this sequence
- end
- the last frame in the source sequence used to create this sequence
- total
- the total number of frames in the source sequence
- Example:
// print the source for the walk animation echo( "walk source:" SPC getField( %this.getSequenceSource( "walk" ), 0 ) );
int TSShapeConstructor::getTargetCount | ( | ) |
Get the number of materials in the shape.
- Returns:
- the number of materials in the shape.
- Example:
%count = %this.getTargetCount();
string TSShapeConstructor::getTargetName | ( | int | index | ) |
Get the name of the indexed shape material.
- Parameters:
-
index index of the material to get (valid range is 0 - getTargetCount()-1).
- Returns:
- the name of the indexed material.
- Example:
%count = %this.getTargetCount(); for ( %i = 0; %i < %count; %i++ ) echo( "Target " @ %i @ ": " @ %this.getTargetName( %i ) );
string TSShapeConstructor::getTrigger | ( | string | name, | |
int | index | |||
) |
Get information about the indexed trigger.
- Parameters:
-
name name of the sequence to query index index of the trigger (valid range is 0 - getTriggerCount()-1)
- Returns:
- string of the form "frame state"
- Example:
// print all triggers in the sequence %count = %this.getTriggerCount( "back" ); for ( %i = 0; %i < %count; %i++ ) echo( %i SPC %this.getTrigger( "back", %i ) );
int TSShapeConstructor::getTriggerCount | ( | string | name | ) |
Get the number of triggers in the specified sequence.
- Parameters:
-
name name of the sequence to query
- Returns:
- number of triggers in the sequence
void TSShapeConstructor::notifyShapeChanged | ( | ) |
Notify game objects that this shape file has changed, allowing them to update internal data if needed.
void TSShapeConstructor::onLoad | ( | ) |
Called immediately after the DTS or DAE file has been loaded; before the shape data is available to any other object (StaticShape, Player etc). This is where you should put any post-load commands to modify the shape in-memory such as addNode, renameSequence etc.
void TSShapeConstructor::onUnload | ( | ) |
Called when the DTS or DAE resource is flushed from memory. Not normally required, but may be useful to perform cleanup.
bool TSShapeConstructor::removeDetailLevel | ( | int | index | ) |
Remove the detail level (including all meshes in the detail level).
- Parameters:
-
size size of the detail level to remove
- Returns:
- true if successful, false otherwise
- Example:
%this.removeDetailLevel( 2 );
bool TSShapeConstructor::removeImposter | ( | ) |
Remove the imposter detail level (if any) from the shape.
- Returns:
- true if successful, false otherwise
bool TSShapeConstructor::removeMesh | ( | string | name | ) |
Remove a mesh from the shape.
If all geometry is removed from an object, the object is also removed.
- Parameters:
-
name full name (object name + detail size) of the mesh to remove
- Returns:
- true if successful, false otherwise
- Example:
%this.removeMesh( "SimpleShape128" );
bool TSShapeConstructor::removeNode | ( | string | name | ) |
Remove a node from the shape.
The named node is removed from the shape, including from any sequences that use the node. Child nodes and objects attached to the node are re-assigned to the node's parent.
- Parameters:
-
name name of the node to remove.
- Returns:
- true if successful, false otherwise.
- Example:
%this.removeNode( "Nose" );
bool TSShapeConstructor::removeObject | ( | string | name | ) |
Remove an object (including all meshes for that object) from the shape.
- Parameters:
-
name name of the object to remove.
- Returns:
- true if successful, false otherwise.
- Example:
// clear all objects in the shape %count = %this.getObjectCount(); for ( %i = %count-1; %i >= 0; %i-- ) %this.removeObject( %this.getObjectName(%i) );
bool TSShapeConstructor::removeSequence | ( | string | name | ) |
Remove the sequence from the shape.
- Parameters:
-
name name of the sequence to remove
- Returns:
- true if successful, false otherwise
bool TSShapeConstructor::removeTrigger | ( | string | name, | |
int | keyframe, | |||
int | state | |||
) |
Remove a trigger from the sequence.
- Parameters:
-
name name of the sequence to modify keyframe keyframe of the trigger to remove state of the trigger to remove
- Returns:
- true if successful, false otherwise
- Example:
%this.removeTrigger( "walk", 3, 1 );
bool TSShapeConstructor::renameDetailLevel | ( | string | oldName, | |
string | newName | |||
) |
Rename a detail level.
- Note:
- Note that detail level names must be unique, so this command will fail if there is already a detail level with the desired name
- Parameters:
-
oldName current name of the detail level newName new name of the detail level
- Returns:
- true if successful, false otherwise
- Example:
%this.renameDetailLevel( "detail-1", "collision-1" );
bool TSShapeConstructor::renameNode | ( | string | oldName, | |
string | newName | |||
) |
Rename a node.
- Note:
- Note that node names must be unique, so this command will fail if there is already a node with the desired name
- Parameters:
-
oldName current name of the node newName new name of the node
- Returns:
- true if successful, false otherwise
- Example:
%this.renameNode( "Bip01 L Hand", "mount5" );
bool TSShapeConstructor::renameObject | ( | string | oldName, | |
string | newName | |||
) |
Rename an object.
- Note:
- Note that object names must be unique, so this command will fail if there is already an object with the desired name
- Parameters:
-
oldName current name of the object newName new name of the object
- Returns:
- true if successful, false otherwise
- Example:
%this.renameObject( "MyBox", "Box" );
bool TSShapeConstructor::renameSequence | ( | string | oldName, | |
string | newName | |||
) |
Rename a sequence.
- Note:
- Note that sequence names must be unique, so this command will fail if there is already a sequence with the desired name
- Parameters:
-
oldName current name of the sequence newName new name of the sequence
- Returns:
- true if successful, false otherwise
- Example:
%this.renameSequence( "walking", "walk" );
void TSShapeConstructor::saveShape | ( | string | filename | ) |
Save the shape (with all current changes) to a new DTS file.
- Parameters:
-
filename Destination filename.
- Example:
%this.saveShape( "./myShape.dts" );
bool TSShapeConstructor::setBounds | ( | Box3F | bbox | ) |
Set the shape bounds to the given bounding box.
- Parameters:
-
Bounding box "minX minY minZ maxX maxY maxZ"
- Returns:
- true if successful, false otherwise
int TSShapeConstructor::setDetailLevelSize | ( | int | index, | |
int | newSize | |||
) |
Change the size of a detail level.
- Note:
- Note that detail levels are always sorted in decreasing size order, so this command may cause detail level indices to change.
- Parameters:
-
index index of the detail level to modify newSize new size for the detail level
- Returns:
- new index for this detail level
- Example:
%this.setDetailLevelSize( 2, 256 );
bool TSShapeConstructor::setMeshMaterial | ( | string | meshName, | |
string | matName | |||
) |
Set the name of the material attached to the mesh.
- Parameters:
-
meshName full name (object name + detail size) of the mesh to modify matName name of the material to attach. This could be the base name of the diffuse texture (eg. "test_mat" for "test_mat.jpg"), or the name of a Material object already defined in script.
- Returns:
- true if successful, false otherwise
- Example:
// set the mesh material %this.setMeshMaterial( "SimpleShape128", "test_mat" );
bool TSShapeConstructor::setMeshSize | ( | string | name, | |
int | size | |||
) |
Change the detail level size of the named mesh.
- Parameters:
-
name full name (object name + current size ) of the mesh to modify size new detail level size
- Returns:
- true if successful, false otherwise.
- Example:
%this.setMeshSize( "SimpleShape128", 64 );
bool TSShapeConstructor::setMeshType | ( | string | name, | |
string | type | |||
) |
Set the display type for the mesh.
- Parameters:
-
name full name (object name + detail size) of the mesh to modify type the new type for the mesh: "normal", "billboard" or "billboardzaxis"
- Returns:
- true if successful, false otherwise
- Example:
// set the mesh to be a billboard %this.setMeshType( "SimpleShape64", "billboard" );
bool TSShapeConstructor::setNodeParent | ( | string | name, | |
string | parentName | |||
) |
Set the parent of a node.
- Parameters:
-
name name of the node to modify parentName name of the parent node to set (use "" to move the node to the root level)
- Returns:
- true if successful, false if failed
- Example:
%this.setNodeParent( "Bip01 Pelvis", "start01" );
bool TSShapeConstructor::setNodeTransform | ( | string | name, | |
TransformF | txfm, | |||
bool | isWorld = false | |||
) |
Set the base transform of a node. That is, the transform of the node when in the root (not-animated) pose.
- Parameters:
-
name name of the node to modify txfm transform string of the form: "pos.x pos.y pos.z rot.x rot.y rot.z rot.angle" isworld (optional) flag to set the local-to-parent or the global transform. If false, or not specified, the position and orientation are treated as relative to the node's parent.
- Returns:
- true if successful, false otherwise
- Example:
%this.setNodeTransform( "mount0", "0 0 1 0 0 1 0" ); %this.setNodeTransform( "mount0", "0 0 0 0 0 1 1.57" ); %this.setNodeTransform( "mount0", "1 0 0 0 0 1 0", true );
bool TSShapeConstructor::setObjectNode | ( | string | objName, | |
string | nodeName | |||
) |
Set the node an object is attached to.
When the shape is rendered, the object geometry is rendered at the node's current transform.
- Parameters:
-
objName name of the object to modify nodeName name of the node to attach the object to
- Returns:
- true if successful, false otherwise
- Example:
%this.setObjectNode( "Hand", "Bip01 LeftHand" );
bool TSShapeConstructor::setSequenceBlend | ( | string | name, | |
bool | blend, | |||
string | blendSeq, | |||
int | blendFrame | |||
) |
Mark a sequence as a blend or non-blend.
A blend sequence is one that will be added on top of any other playing sequences. This is done by storing the animated node transforms relative to a reference frame, rather than as absolute transforms.
- Parameters:
-
name name of the sequence to modify blend true to make the sequence a blend, false for a non-blend blendSeq the name of the sequence that contains the blend reference frame blendFrame the reference frame in the blendSeq sequence
- Returns:
- true if successful, false otherwise
- Example:
%this.setSequenceBlend( "look", true, "root", 0 );
bool TSShapeConstructor::setSequenceCyclic | ( | string | name, | |
bool | cyclic | |||
) |
Mark a sequence as cyclic or non-cyclic.
- Parameters:
-
name name of the sequence to modify cyclic true to make the sequence cyclic, false for non-cyclic
- Returns:
- true if successful, false otherwise
- Example:
%this.setSequenceCyclic( "ambient", true ); %this.setSequenceCyclic( "shoot", false );
bool TSShapeConstructor::setSequenceGroundSpeed | ( | string | name, | |
Point3F | transSpeed, | |||
Point3F | rotSpeed = Point3F::Zero | |||
) |
Set the translation and rotation ground speed of the sequence.
The ground speed of the sequence is set by generating ground transform keyframes. The ground translational and rotational speed is assumed to be constant for the duration of the sequence. Existing ground frames for the sequence (if any) will be replaced.
- Parameters:
-
name name of the sequence to modify transSpeed translational speed (trans.x trans.y trans.z) in Torque units per frame rotSpeed (optional) rotational speed (rot.x rot.y rot.z) in radians per frame. Default is "0 0 0"
- Returns:
- true if successful, false otherwise
- Example:
%this.setSequenceGroundSpeed( "run", "5 0 0" ); %this.setSequenceGroundSpeed( "spin", "0 0 0", "4 0 0" );
bool TSShapeConstructor::setSequencePriority | ( | string | name, | |
float | priority | |||
) |
Set the sequence priority.
- Parameters:
-
name name of the sequence to modify priority new priority value
- Returns:
- true if successful, false otherwise
void TSShapeConstructor::writeChangeSet | ( | ) |
Write the current change set to a TSShapeConstructor script file. The name of the script file is the same as the model, but with .cs extension. eg. myShape.cs for myShape.dts or myShape.dae.
Member Data Documentation
Translate COLLADA model on import so the origin is at the center. No effect for DTS files.
Translate COLLADA model on import so origin is at the (Z axis) bottom of the model. No effect for DTS files.
This can be used along with adjustCenter to have the origin at the center of the bottom of the model.
- See also:
- adjustCenter
TAB separated patterns of nodes to import even if in neverImport list. No effect for DTS files.
Torque allows unwanted nodes in COLLADA (.dae) files to to be ignored during import. This field contains a TAB separated list of patterns to match node names. Any node that matches one of the patterns in the list will always be imported, even if it also matches the neverImport list
- See also:
- neverImport
- Example:
singleton TSShapeConstructor(MyShapeDae) { baseShape = "./myShape.dae"; alwaysImport = "mount*" TAB "eye"; neverImport = "*-PIVOT"; }
TAB separated patterns of meshes to import even if in neverImportMesh list. No effect for DTS files.
Torque allows unwanted meshes in COLLADA (.dae) files to to be ignored during import. This field contains a TAB separated list of patterns to match mesh names. Any mesh that matches one of the patterns in the list will always be imported, even if it also matches the neverImportMesh list
- See also:
- neverImportMesh
- Example:
singleton TSShapeConstructor(MyShapeDae) { baseShape = "./myShape.dae"; alwaysImportMesh = "body*" TAB "armor" TAB "bounds"; neverImportMesh = "*-dummy"; }
filename TSShapeConstructor::baseShape |
Specifies the path to the DTS or DAE file to be operated on by this object.
Since the TSShapeConstructor script must be in the same folder as the DTS or DAE file, it is recommended to use a relative path so that the shape and script files can be copied to another location without having to modify the path.
Forces update of the materials.cs file in the same folder as the COLLADA (.dae) file, even if Materials already exist. No effect for DTS files.
Normally only Materials that are not already defined are written to materials.cs.
Ignore <scale> elements inside COLLADA <node>s. No effect for DTS files.
This field is a workaround for certain exporters that generate bad node scaling, and is not usually required.
TSShapeConstructorLodType TSShapeConstructor::lodType |
Control how the COLLADA (.dae) importer interprets LOD in the model. No effect for DTS files.
Set to one of the following values:
- DetectDTS
- The default value. Instructs the importer to search for a 'baseXXX->startXXX' node hierarchy at the root level. If found, the importer acts as if ''TrailingNumber'' was set. Otherwise, all geometry is imported at a single detail size.
- SingleSize
- All geometry is imported at a fixed detail size. Numbers at the end of geometry node's are ignored.
- TrailingNumber
- Numbers at the end of geometry node's name are interpreted as the detail size (similar to DTS exporting). Geometry instances with the same base name but different trailing number are grouped into the same object.
- DEFAULT
- The default value. Use the value in the .dae file (defaults to Z_AXIS if the <up_axis> element is not present).
Prefix to apply to all material map names in the COLLADA (.dae) file. No effect for DTS files.
This field is useful to avoid material name clashes for exporters that generate generic material names like "texture0" or "material1".
TAB separated patterns of nodes to ignore on loading. No effect for DTS files.
Torque allows unwanted nodes in COLLADA (.dae) files to to be ignored during import. This field contains a TAB separated list of patterns to match node names. Any node that matches one of the patterns in the list will not be imported (unless it matches the alwaysImport list.
- See also:
- alwaysImport
TAB separated patterns of meshes to ignore on loading. No effect for DTS files.
Torque allows unwanted meshes in COLLADA (.dae) files to to be ignored during import. This field contains a TAB separated list of patterns to match mesh names. Any mesh that matches one of the patterns in the list will not be imported (unless it matches the alwaysImportMesh list.
- See also:
- alwaysImportMesh
filename TSShapeConstructor::sequence |
Legacy method of adding sequences to a DTS or DAE shape after loading.
- Example:
singleton TSShapeConstructor(MyShapeDae) { baseShape = "./myShape.dae"; sequence = "../anims/root.dae root"; sequence = "../anims/walk.dae walk"; sequence = "../anims/jump.dsq jump"; }
Sets the detail size when lodType is set to SingleSize. No effect otherwise, and no effect for DTS files.
- See also:
- lodType
float TSShapeConstructor::unit |
Override the <unit> element in the COLLADA (.dae) file. No effect for DTS files.
COLLADA (.dae) files usually contain a <unit> element that indicates the 'real world' units that the model is described in. It means you can work in sensible and meaningful units in your modeling app.
For example, if you were modeling a small object like a cup, it might make sense to work in inches (1 MAX unit = 1 inch), but if you were modeling a building, it might make more sense to work in feet (1 MAX unit = 1 foot). If you export both models to COLLADA, T3D will automatically scale them appropriately. 1 T3D unit = 1 meter, so the cup would be scaled down by 0.0254, and the building scaled down by 0.3048, given them both the correct scale relative to each other.
Omit the field or set to -1 to use the value in the .dae file (1.0 if the <unit> element is not present)
TSShapeConstructorUpAxis TSShapeConstructor::upAxis |
Override the <up_axis> element in the COLLADA (.dae) file. No effect for DTS files.
Set to one of the following values:
- X_AXIS
- Positive X points up. Model will be rotated into Torque's coordinate system (Z up).
- Y_AXIS
- Positive Y points up. Model will be rotated into Torque's coordinate system (Z up).
- Z_AXIS
- Positive Z points up. No rotation will be applied to the model.
- DEFAULT
- The default value. Use the value in the .dae file (defaults to Z_AXIS if the <up_axis> element is not present).