1.4's DynamicTexture and GUIs
by Tom Spilman · in Torque Game Engine Advanced · 05/04/2005 (2:07 am) · 102 replies
I'm currently looking to add rendering and interacting with a GuiControl mapped on to a shape or interior surface. First i'm trying to figure out what the best way to place this functionality into TSE. I looked at DynamicTexture from 1.4, but it's just a class and really doesn't elaborate on how it can/should be used in the overal flow of the engine.
Ideally the workflow would be like so:
1. Artist makes some *thing* and adds a dummy texture with a special name on it for the surface where the gui will be mapped.
2. The material is added which somehow marks one of it's textures as being a "gui texture" and the name of the GuiControl to render to it.
3. Thru a raycast i should be able to find the material hit and if it has a GuiControl associated with it. If so it activates it for interactivity.
Step 1 is easy. At the moment i'm mostly concerned with step 2.
Ideally this functionality would go into the Material class itself and not CustomMaterial or some other class derived from Material. This would allow a so called GuiTexture to be assigned to any stage/texture property and give the artist the most flexibility with effects overlaid on the gui texture.
I was thinking of something along the lines of what CustomMaterial does for it's special textures like $cubemap, $lightmap, $fog, $backbuff, etc. You could specify a $gui for one of the texture stages and have a gui property on the material datablock which is the guicontrol to assign to that GuiTexture.
Still... who updates the textures and GuiControls? I'm just starting to dig into this, but has anyone have any thoughts on how to integrate such a system into TSE?
Ideally the workflow would be like so:
1. Artist makes some *thing* and adds a dummy texture with a special name on it for the surface where the gui will be mapped.
2. The material is added which somehow marks one of it's textures as being a "gui texture" and the name of the GuiControl to render to it.
3. Thru a raycast i should be able to find the material hit and if it has a GuiControl associated with it. If so it activates it for interactivity.
Step 1 is easy. At the moment i'm mostly concerned with step 2.
Ideally this functionality would go into the Material class itself and not CustomMaterial or some other class derived from Material. This would allow a so called GuiTexture to be assigned to any stage/texture property and give the artist the most flexibility with effects overlaid on the gui texture.
I was thinking of something along the lines of what CustomMaterial does for it's special textures like $cubemap, $lightmap, $fog, $backbuff, etc. You could specify a $gui for one of the texture stages and have a gui property on the material datablock which is the guicontrol to assign to that GuiTexture.
Still... who updates the textures and GuiControls? I'm just starting to dig into this, but has anyone have any thoughts on how to integrate such a system into TSE?
About the author
Tom is a programmer and co-owner of Sickhead Games, LLC.
#62
06/22/2006 (1:30 pm)
Hehe...awesome reference. Curious myself how this is progressing!
#63
06/22/2006 (8:56 pm)
It's been over a month. I'm curious to.
#64
06/23/2006 (7:49 am)
I ran into some rough spots and put it aside for a day or two, and then got busy with the MMOKIT. I am spending time on it today though, and will post my progress later. Hopefully I can finish it up or bring it darn near close.
#65
06/25/2006 (7:30 am)
Or post it so someone else can make a resource out of it?
#66
06/26/2006 (7:40 am)
It went well Friday with just a few remaining areas to clean up. If I can't nail them down very quickly I will ask for some help.
#67
07/07/2006 (7:39 pm)
It's been over a week since the last post.. I know that isn't much time but I am very curious as to the current status of this and would be very excited to see this implimented in TSE as part of the engine.
#68
07/10/2006 (9:28 pm)
Curious to know how applicable this would be to making dynamic content mapped onto a model. I'd like to give the player a small GPS-like unit in their hands that shows their current position, speed, heading and altitude and it seems like a natural application of dynamic textures.
#69
This is before the optimizations that Tom recommended too, this is just getting it to run...
07/11/2006 (1:22 pm)
This is going well, I am finally able to get it to compile with the new 3.5. I did not have RigidShapes implemented yet, so as soon as I get that in I can finally test this.... This is before the optimizations that Tom recommended too, this is just getting it to run...
#70

This is the Options gui rendered to a texture on a shape.
Still don't have a player object in yet, so I cant click on anything, but I am obviously getting closer!
07/11/2006 (1:36 pm)
Maybe I spoke too soon! RigidShape was pretty easy to get working...
This is the Options gui rendered to a texture on a shape.
Still don't have a player object in yet, so I cant click on anything, but I am obviously getting closer!
#71
07/13/2006 (1:23 am)
Right now the holdup for me is finding out how to get the material from the raycast. If anyone has a tip to save time, I welcome it!
#72
07/13/2006 (3:17 am)
It's in the rayinfo struct - try looking at the way the player does footdust.
#73
I thought the material info would be in the rayinfo struct too but the .material always comes back as 0 and getting the material list from the object itself isnt going to work because the gui portion of the texture is only on certain faces.
So it looks like what I really need is how to figure out which face was struck, then I can use the code Tom posted above for similar use on interiors:
Edit
I just found this in tsMesh's castray:
rayInfo->material = curMaterial;
So it should be returning a material index instead of 0
I guess I will have to look at why that is happening, thanks for the tip.
07/13/2006 (3:32 am)
The footpuffs are a little easier because they just get a material list from the terrain, and we know that the player collided with the terrain if they are in a TriggerLeft or TriggerRight state, otherwise they wouldnt be walking.I thought the material info would be in the rayinfo struct too but the .material always comes back as 0 and getting the material list from the object itself isnt going to work because the gui portion of the texture is only on certain faces.
So it looks like what I really need is how to figure out which face was struck, then I can use the code Tom posted above for similar use on interiors:
if(inside)
{
info->face = surfaceIndex;
// TOM: This returns the material id of the surface hit.
MatInstance* matInst = mMaterialList->getMaterialInst( rSurface.textureIndex );
if ( matInst && matInst->getMaterial() )
{
info->material = matInst->getMaterial()->getId();
}
break;
}Edit
I just found this in tsMesh's castray:
rayInfo->material = curMaterial;
So it should be returning a material index instead of 0
I guess I will have to look at why that is happening, thanks for the tip.
#74
07/13/2006 (3:46 am)
0 is a valid material index, btw.
#75
The test shape in question has 3 different materials on it, and the index always comes back as 0 no matter where I click on the object. One of these materials is the guiTextureCanvas, and that's the one I need to be able to find.
I am tracking through the castray stack right now to find out why this is. I did find in one of the functions Tom sent that he built a raycast function into the guiTextureCanvas object that is already pulling material info out of the raycast. In this case however the function is not being called at all because (I believe) the raycast cant figure out that it hit a guiTextureCanvas without the correct material index.
Here is the stack that I can follow:
(sceneobject.cpp):
Console containerRayCast
container::castRay
SceneObject::castRay
^^this is a bool function hardcoded to return false!
So I don't even see the possibility of the containercastray function being able to chain up a castray call to the object itself. I must be missing something, but I'm not sure what yet.
Getting there! Learning a lot.
07/13/2006 (5:20 am)
It is certainly! There are a few places in the enigne where it gets set to 0 too though.The test shape in question has 3 different materials on it, and the index always comes back as 0 no matter where I click on the object. One of these materials is the guiTextureCanvas, and that's the one I need to be able to find.
I am tracking through the castray stack right now to find out why this is. I did find in one of the functions Tom sent that he built a raycast function into the guiTextureCanvas object that is already pulling material info out of the raycast. In this case however the function is not being called at all because (I believe) the raycast cant figure out that it hit a guiTextureCanvas without the correct material index.
Here is the stack that I can follow:
(sceneobject.cpp):
Console containerRayCast
container::castRay
SceneObject::castRay
^^this is a bool function hardcoded to return false!
So I don't even see the possibility of the containercastray function being able to chain up a castray call to the object itself. I must be missing something, but I'm not sure what yet.
Getting there! Learning a lot.
#76
Notice it's a static method. This allows it to be called from TorqueScript like so...
The intent is that you first do a normal raycast to figure out which shape you hit. If it's a mesh shape then you do a GuiTextureCanvas::castRay call to figure out which material was hit.
The reason i made it two steps was that to figure out the material hit within a mesh involved an expensive per-triangle ray check (this is the special TSMesh::castRayTri() function i added). I couldn't add this to the normal ContainerRayCast as it would cause a huge performance drain on normal ray casts which normally do not need material info.
Thinking about this now maybe a better solution is to add a special flag to ContainerRayCast which can be used to toggle the check for the material hit. This would be helpful for future work with fetching material types for impacts/footsteps, but to do this right it would require a change to the function signature for SceneObject::castRay().
07/13/2006 (9:19 am)
@Dave - Indeed i did add a castRay function to my GuiTextureCanvas class:ConsoleStaticMethod( GuiTextureCanvas, castRay, const char*, 4, 4, "(ShapeBase object, Point3F start, Point3F end)")
Notice it's a static method. This allows it to be called from TorqueScript like so...
GuiTextureCanvas::castRay( %object, %start, %end );
The intent is that you first do a normal raycast to figure out which shape you hit. If it's a mesh shape then you do a GuiTextureCanvas::castRay call to figure out which material was hit.
The reason i made it two steps was that to figure out the material hit within a mesh involved an expensive per-triangle ray check (this is the special TSMesh::castRayTri() function i added). I couldn't add this to the normal ContainerRayCast as it would cause a huge performance drain on normal ray casts which normally do not need material info.
Thinking about this now maybe a better solution is to add a special flag to ContainerRayCast which can be used to toggle the check for the material hit. This would be helpful for future work with fetching material types for impacts/footsteps, but to do this right it would require a change to the function signature for SceneObject::castRay().
#77
07/13/2006 (9:23 am)
Well I'll be darned. This little resource project has taught me quite abit. Nice work Tom, thanks for the info!!!
#78
The one thing I love about this game engine, is the community surrounding it!
Great work guys, hope it can get slapped into head.
07/13/2006 (4:26 pm)
Mmmm, looks good!The one thing I love about this game engine, is the community surrounding it!
Great work guys, hope it can get slapped into head.
#79
I am going to look at a couple optimizations before I write up the resource:
1) Scaling - the Guis either need to scale as the object scales, or you always have to have the object scale as 1
2) Interiors - make this work with interiors.
07/14/2006 (4:18 am)
That was the last piece of the puzzle! I was quite shocked to see that not only did the material come back, but the onscreen gui responded as well. This is working!!I am going to look at a couple optimizations before I write up the resource:
1) Scaling - the Guis either need to scale as the object scales, or you always have to have the object scale as 1
2) Interiors - make this work with interiors.
#80
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=10899
I thought I'd post it up and get some feedback before I moved to improve what was there.
07/14/2006 (12:16 pm)
Ok, the first version of the resource is now available:www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=10899
I thought I'd post it up and get some feedback before I moved to improve what was there.
Associate Tom Spilman
Sickhead Games
... what are you doing, Dave?