TorqueX - First Stab at Hiding Mesh Resource
by David Everhart · 07/08/2008 (7:26 pm) · 3 comments
When I started to think of character customization, I was doing Arillian in 2D at the time. I used an approach similar to Diablo 2's style. However, per my last blog post, I am now in the 3D world. I looked around, and came upon a resource:
Hiding Meshes resource
I studied it and researched all the pieces it touched. I asked on the forums if anyone had attempted this, but had no replies. I rolled up my sleeves, and decided to take a stab at it. I decided to do a prototype, and see if I could get the meshes to swap in and out at runtime. One of the first questions I had was, how the heck do you build your model? I didnt really know how to go about this , so did some research, and realized I needed a model made up of multiple meshes.
In Lightwave 9, They use layers, like in photoshop. The thought crossed my mind, that maybe I could model the various bodyparts on individual layers, then export the model. I built a basic testman, with 5 layers dedicated to a blue testman, and 5 layers dedicated to a red testman. Below are some pictures.

This picture shows blue feet on layer 1 (Circled in red).

This picture shows blue Legs on layer 2 (Circled in red).

This picture shows all 5 layers for the blue testman (Layers 1-5 circled in red) .

This picture shows all 5 layers for the redtestman (Layers 11-15 circled in red) . The reason the layers arent 6-10 is because I wanted each layer bank (10 layers) to house one character setup. When you export, you can hide the layers with nothing on them .
In all, I used 10 layers. Now I had to export the model to a DTS. Below are some pictures of that:

This picture shows the meshes it found in the model.

The DTSNames are horrible, so I decided to change them, and I had to set each of them to export as a node or mesh, as depicted in the picture above.

When it was all set, the export looked like the above. Now that I had My model, it was time to get the model into the game. I used John Kanalkis's Create Player Function to do just that. I popped it into my game.cs.
I added a name to the model, so I can reference it later on. The next step I had to figure out , was how do you actually turn the meshes on and off. Looking at the C++ Hiding resources, it looked like they were manipulating the visibility of the meshes. So after some digging, I found it in the tsShapeInstance class. There is an internal _meshObjects that is an objectinstance[]. I needed to manipulate the meshes in there, so I added a public property to the class.
Now that I had access to the meshes, I needed to be able to control the visibility of them. I decided to group all the related mesh functionality into a class called MeshManager . I decided to make it a static class , although a singleton could have worked as well. It has 5 functions:
ShowMesh(string modelName,string meshName)
HideMesh(string modelName, string meshName)
HideAllMeshes(string modelName)
ShowAllMeshes(string modelName)
ListMeshes(string modelName,bool showHidden, bool showVisible)
Here is the code for it:
It doesnt have all its exception handling, and is not fully refactored yet,but for my prototype, that is ok. Now that I have a meshmanager, I decided to test it by putting this in my begin run:
The result is below:

I hid all the meshes initially for the CurrentPlayer Object, then showed the 5 red meshes. Now, in order for me to test the functionality of the other functions, I wanted to use the console. In order for me to call custom methods from the torqueX console (accessed via ~), I had to extend it, with this great resource:
Extending the TorqueX Console
Once I implemented that, I added a class to handle all the custom methods , so that I could call them directly from the console.

Here I hide the Red head mesh, with a HideMesh call.

Now I show the Blue head mesh, with a ShowMesh call.

In the above picture, I list all the meshes and their current state.
The next step for me, is to create some basic animations, and test how the meshes react when switching on and off in an animation. Ok, its been a loooong post, so I will post the results of the animation one when I am done. Until then!
Hiding Meshes resource
I studied it and researched all the pieces it touched. I asked on the forums if anyone had attempted this, but had no replies. I rolled up my sleeves, and decided to take a stab at it. I decided to do a prototype, and see if I could get the meshes to swap in and out at runtime. One of the first questions I had was, how the heck do you build your model? I didnt really know how to go about this , so did some research, and realized I needed a model made up of multiple meshes.
In Lightwave 9, They use layers, like in photoshop. The thought crossed my mind, that maybe I could model the various bodyparts on individual layers, then export the model. I built a basic testman, with 5 layers dedicated to a blue testman, and 5 layers dedicated to a red testman. Below are some pictures.

This picture shows blue feet on layer 1 (Circled in red).

This picture shows blue Legs on layer 2 (Circled in red).

This picture shows all 5 layers for the blue testman (Layers 1-5 circled in red) .

This picture shows all 5 layers for the redtestman (Layers 11-15 circled in red) . The reason the layers arent 6-10 is because I wanted each layer bank (10 layers) to house one character setup. When you export, you can hide the layers with nothing on them .
In all, I used 10 layers. Now I had to export the model to a DTS. Below are some pictures of that:

This picture shows the meshes it found in the model.

The DTSNames are horrible, so I decided to change them, and I had to set each of them to export as a node or mesh, as depicted in the picture above.

When it was all set, the export looked like the above. Now that I had My model, it was time to get the model into the game. I used John Kanalkis's Create Player Function to do just that. I popped it into my game.cs.
public void CreatePlayer()
{
//create the simple torque object
TorqueObject objPlayer = new TorqueObject();
objPlayer.Name = "CurrentPlayer";
//create the render component
T3DTSRenderComponent componentRender = new T3DTSRenderComponent();
componentRender.ShapeName = @"data\Skeleton\test.dts";
//create the scene component
T3DSceneComponent componentScene = new T3DSceneComponent();
componentScene.Position = new Vector3(1024, 1024, 295);
//add both of the components
objPlayer.Components.AddComponent(componentRender);
objPlayer.Components.AddComponent(componentScene);
//register the object
TorqueObjectDatabase.Instance.Register(objPlayer);
}I added a name to the model, so I can reference it later on. The next step I had to figure out , was how do you actually turn the meshes on and off. Looking at the C++ Hiding resources, it looked like they were manipulating the visibility of the meshes. So after some digging, I found it in the tsShapeInstance class. There is an internal _meshObjects that is an objectinstance[]. I needed to manipulate the meshes in there, so I added a public property to the class.
/// <summary>
/// Gets and sets the array of meshes for the shape.
/// </summary>
public ObjectInstance[] MeshObjects
{
get { return _meshObjects; }
set { _meshObjects = value; }
}Now that I had access to the meshes, I needed to be able to control the visibility of them. I decided to group all the related mesh functionality into a class called MeshManager . I decided to make it a static class , although a singleton could have worked as well. It has 5 functions:
ShowMesh(string modelName,string meshName)
HideMesh(string modelName, string meshName)
HideAllMeshes(string modelName)
ShowAllMeshes(string modelName)
ListMeshes(string modelName,bool showHidden, bool showVisible)
Here is the code for it:
using System;
using System.Collections.Generic;
using System.Text;
using GarageGames.Torque.Core;
using GarageGames.Torque.SceneGraph;
using GarageGames.Torque.Sim;
using GarageGames.Torque.GameUtil;
using GarageGames.Torque.T2D;
using GarageGames.Torque.Platform;
using GarageGames.Torque.GUI;
using GarageGames.Torque.T3D;
using GarageGames.Torque.TS;
using GarageGames.Torque.GFX;
namespace StarterGame3D
{
public class MeshManager
{
public static void ShowMesh(string modelName,string meshName)
{
SetMeshVisibility(modelName,meshName, true);
}
public static void HideMesh(string modelName, string meshName)
{
SetMeshVisibility(modelName,meshName, false);
}
public static void HideAllMeshes(string modelName)
{
TorqueObject model = TorqueObjectDatabase.Instance.FindObject<TorqueObject>(modelName);
T3DTSRenderComponent componentRender = model.Components.FindComponent<T3DTSRenderComponent>();
for (int index = 0; index < componentRender.Shape.Objects.Length; index++)
{
componentRender.ShapeInstance.MeshObjects[index].Visibility = 0.0f;
}
}
public static void ShowAllMeshes(string modelName)
{
TorqueObject model = TorqueObjectDatabase.Instance.FindObject<TorqueObject>(modelName);
T3DTSRenderComponent componentRender = model.Components.FindComponent<T3DTSRenderComponent>();
for (int index = 0; index < componentRender.Shape.Objects.Length; index++)
{
componentRender.ShapeInstance.MeshObjects[index].Visibility = 1.0f;
}
}
private static void SetMeshVisibility(string modelName, string meshName, bool visible)
{
TorqueObject model = TorqueObjectDatabase.Instance.FindObject<TorqueObject>(modelName);
T3DTSRenderComponent componentRender = model.Components.FindComponent<T3DTSRenderComponent>();
for (int objectIndex = 0; objectIndex < componentRender.Shape.Objects.Length; objectIndex++)
{
if (componentRender.Shape.Names[componentRender.Shape.Objects[objectIndex].NameIndex].ToUpper() == meshName.ToUpper())
{
if (visible)
{
componentRender.ShapeInstance.MeshObjects[objectIndex].Visibility = 1.0f;
}
else
{
componentRender.ShapeInstance.MeshObjects[objectIndex].Visibility = 0.0f;
}
}
}
}
public static List<string> ListMeshes(string modelName,bool showHidden, bool showVisible)
{
TorqueObject model = TorqueObjectDatabase.Instance.FindObject<TorqueObject>(modelName);
T3DTSRenderComponent componentRender = model.Components.FindComponent<T3DTSRenderComponent>();
List<string> meshes = new List<string>();
string mesh = "";
for (int objectIndex = 0; objectIndex < componentRender.Shape.Objects.Length; objectIndex++)
{
float meshVisibility = componentRender.ShapeInstance.MeshObjects[objectIndex].Visibility;
if (showVisible && meshVisibility == 1.0f)
{
mesh = "MeshName:" + componentRender.Shape.Names[componentRender.Shape.Objects[objectIndex].NameIndex] + "||Visibility:Visible";
meshes.Add(mesh);
}
if (showHidden && meshVisibility == 0.0f)
{
mesh = "MeshName:" + componentRender.Shape.Names[componentRender.Shape.Objects[objectIndex].NameIndex] + "||Visibility:Hidden";
meshes.Add(mesh);
}
}
return meshes;
}
}
}It doesnt have all its exception handling, and is not fully refactored yet,but for my prototype, that is ok. Now that I have a meshmanager, I decided to test it by putting this in my begin run:
MeshManager.HideAllMeshes("CurrentPlayer");
MeshManager.ShowMesh("CurrentPlayer", "RedFeet");
MeshManager.ShowMesh("CurrentPlayer", "RedLegs");
MeshManager.ShowMesh("CurrentPlayer", "RedTorso");
MeshManager.ShowMesh("CurrentPlayer", "RedArms");
MeshManager.ShowMesh("CurrentPlayer", "RedHead");The result is below:

I hid all the meshes initially for the CurrentPlayer Object, then showed the 5 red meshes. Now, in order for me to test the functionality of the other functions, I wanted to use the console. In order for me to call custom methods from the torqueX console (accessed via ~), I had to extend it, with this great resource:
Extending the TorqueX Console
Once I implemented that, I added a class to handle all the custom methods , so that I could call them directly from the console.

Here I hide the Red head mesh, with a HideMesh call.

Now I show the Blue head mesh, with a ShowMesh call.

In the above picture, I list all the meshes and their current state.
The next step for me, is to create some basic animations, and test how the meshes react when switching on and off in an animation. Ok, its been a loooong post, so I will post the results of the animation one when I am done. Until then!
About the author
#2
John K.
07/08/2008 (8:48 pm)
David, this is really impressive!!! Perfect for character customization within a game. I'm very interested in giving this a try. Good Work.John K.
#3
07/09/2008 (6:17 am)
Thanks guys. It has been a lot of fun working on this so far. I am very curious as to what animation will do to the mesh edges. Guess I will find out :) 
Torque 3D Owner Josef Rogovsky
Keep 'em coming!