Game Development Community

Example using collada and TSShapeConstructor

by Jay Crossler · in Torque 3D Professional · 07/01/2009 (10:35 am) · 18 replies

I'm having a bit of a mental block getting the Collada imports (using Sketchup) and then modifying objects with TSShapeConstructor. I'm trying to put together a lesson on how to do this to show some high-school students.

Can someone walk me through the simplest steps I would take? I'm trying to do this using only opensource/freeware tools (other than Torque3d):

I'm looking to make a planetarium - have multiple planets (spheres) each with different textures on them. So I think the steps would be to:

-Create a sphere in Anim8or (use steps: http://www.barnabu.co.uk/textured-globe-models-in-sketchup-tutorial/)
-Texture sphere (using mars texture at: http://planetpixelemporium.com/mars.html)
-- Export as 3DS, import that into Sketchup.
-- Smooth it, then export as KMZ (then unpack the .kmz as zip files aren't working yet)

-When I add the shape in the World Editor, I have to click on the shape, then go into material editor and choose the correct Diffuse texture

(This all works great, though I'm having trouble figuring out how to do many of these steps using TorqueScript).

The problem I'm having is getting multiple shapes into WorldEditor - each has the same texture name, so editing one texture edits each sphere.

So, questions:
- Do I need to make a different material.cs for each shape?
- How do I point each shape to a different material.cs? I see in the .mis file where the TSStatic has been added. Is there a place to specify which material to apply to the shape?
- How would I do this in script?
- Because the shape has different nodes from Sketchup, do I need to use code/shape editor to build the proper node structure?

Ideally, I'd like to have a function that:
- For each planet_id in an array
-- create a new sphere
-- texture it with the proper texture
-- give it the proper scale and position

#1
07/01/2009 (8:21 pm)
Wow, I think I'm going about this a bit too complicated. After trolling the GG training videos, I found one that I missed before: http://www.vimeo.com/3721271

This shows how to use Autodesk's Mod Tool to build a simple object and build a material.cs file. This looks like just what I needed. If I put something together, I'll upload it as a resource.
#2
07/02/2009 (1:05 am)
My opinion is not always the best one but here we go.
I would get Truespace:

http://www.garagegames.com/community/forums/viewthread/92937


Grab 7-zip if you don't have it. (This works great for extracting .kmz files)

http://www.7-zip.org/


Truespace exports to Collada 1.4.1. There is also a .dts exporter if you wanted to go that way.

As for the material.cs file well the material editor in T3D is making editing materials really really simple. If all you want to do is change the texture on the planet then it shouldn't be that difficult.

If you want a different aspect on the solution in question. You could take this alternative approach.

I would open Truespace and create a sphere. Map a base texture to it. It really doesn't matter what texture it is. Create the different animation sequence of it spinning rotation speeds. IE. rot1, rot2, rot3, rot4, rot5, etc.

Then I would create an IFL (Image File List) and I would have all of the textures of the different planets and make a animation sequence and call it planetChange or something.

I could then export it to collada and import it into the T3D. First I would test the shape as an Interior because thats the easiest one. Just place the collada shape in the art/interiors/collada/ directory. In game you can just load it up and see if it shows up. If it does show up at the appropriate size then we can go back to do the scripting.


#3
07/02/2009 (1:44 am)
Quote:Do I need to make a different material.cs for each shape?

It is not essential, but generally you create a materials.cs script for each shape file (DTS or DAE) to specify the properties of the materials in that shape.

Quote:How do I point each shape to a different material.cs?

You don't point a shape at a materials.cs => you map a Material object (specified in a materials.cs script) to a material in a shape. eg. if your shape contained a material called 'planet_surface', you might have something like this in your materials.cs script:

singleton Material(PlanetMaterial)
{
   mapTo = "planet_surface";  // map this object to shape material
   diffuseMap[0] = "mars";    // diffuse texture is mars.jpg
};

Unfortunately (as you found), since all instances of the shape share the same material, they will all look the same.

Quote:I see in the .mis file where the TSStatic has been added. Is there a place to specify which material to apply to the shape? How would I do this in script?

Unfortunately not.

Quote:Because the shape has different nodes from Sketchup, do I need to use code/shape editor to build the proper node structure?

For static models, you probably don't need to modify the node structure.
#4
07/02/2009 (1:45 am)
What I mean by scripting is: Because we want to use animations to change how our shapes look we will have to use a GameBased object type or create one that support animations. For simplicity (mostly because I'm still learning myself). Lets use the shapebased object StaticShapeData. You can read more about the Hirarchy here:
tdn.garagegames.com/wiki/DTS/Scripting/Hierarchy

StaticShapeData is the datablock name for a StaticShape which supports animations.
$numberOfSlavePlanets = 2;

datablock(slavePlanetDefault)
{
   shapeFile = sphereWithRotAndplanetChangeAnimations; //the directory path yours will abviously be different

};
datablock(slavePlanet0 : slavePlanetDefault)
{
   scale = "1 1 1";
};

datablock(slavePlanet1 : slavePlanetDefault)
{
   scale = "2 2 2";
};

datablock(slavePlanet2 : slavePlanetDefault)
{
   scale = ".4 .4 .4";
};

function spawnMyPlanetsSlave()
{
   for(%i = 0; %i < $numberOfSlavePlanets; %i++)
   {
      %p = new StaticShape("planet" @ %i){
      
      datablock = slavePlanet @ %i;   
         
      };
    
      addMissionCleanup(%p);
     
      //This is where you setup your animation sequences
      //Torque allows be default 4 animation threads per gamebased object

      %p.playThread(0, "rot" @ %i); //play the rot1 animation
      
//play the changePlanet IFL and stop it at the appropriate time line.
      %p.playThread(1, "changePlanet");
      
//every 1000 is a second so if it had 10 textures at 1 frames a second then every 1000 ish. 0 would be first texture and 1000 would be second texture 2000 would be the third etc.
      %theWait = %i * 1000;
      schedule(%theWait , %p.stopThread(1));
      
   }
}
#5
07/02/2009 (1:54 am)
Whenever I worked with the Sketchup Model / KZM exported files I had to do some configuration changes with the collada file in order to organize them appropriately.

First I had to extract the Collada file and the materials associated with them. I placed them into my art/interiors/collada/ directory.
Test.dae
Material0.png
Material1.png
Material2.png

I then renamed the material files for organizational purposes so that it looked like this:
Test0.png
Test1.png
Test2.png

I then opened up the Test.dae and located the image locations(Normally it was close to the top of the file). I put the correct name and directory to find them in. After doing this to each KZM file I never had a problem using the sketchup files.
#6
07/02/2009 (1:50 pm)
Thank you very much for your inputs and suggestions. I spent a while trying to get spheres working, but they kept rendering only a portion of the shape. Then I realized that the images I were using weren't square. I changed the size to 1024x1024 and that fixed the texture rendering issues. I should have remembered that, but it's been awhile.

Using MilkShape, I created a sphere that wraps the images well. I created 5 different textures (one for each planet). When I export it to collada, then import it into Torque, it works well. A problem is that when I use the Material Editor, I only see one of the textures (surface_jupiter) instead of all 5 as options. (this is when I import it as a shape, not an interior).

When I export it as a DTS from milkshape, I do see each of those textures in the Material Editor. Though it's a bit of unexpected behavior - when I select under the Material Properties the material (change it to surface_mars), the texture doesn't change on the object. I can't find any way to see the new textures other than to do it in script. Am I missing something?

I have the file at: wecreategames.com/apps/planets/planets.zip
#7
07/02/2009 (9:39 pm)
JesseL, I tried to follow your suggestions but am having a basic object creation problem. Here's the code I came up with, before adding in animations and other things:
$numberOfPlanets = 8;

datablock StaticShapeData(PlanetDataBlock) {
    category = "Planetoids";
    canSaveDynamicFields = "1";
};


datablock StaticShapeData(Planet0 : PlanetDataBlock) {  
    shapeFile = "art/shapes/planets/sol.dts";
    scale = "1 1 1";  
};  
datablock StaticShapeData(Planet1 : PlanetDataBlock) {  
    shapeFile = "art/shapes/planets/mercury.dts";
    scale = "1 1 1";  
};  
datablock StaticShapeData(Planet2 : PlanetDataBlock) {  
    shapeFile = "art/shapes/planets/venus.dts";
    scale = "1 1 1";
};  
datablock StaticShapeData(Planet3 : PlanetDataBlock) {  
    shapeFile = "art/shapes/planets/earth.dts";
    scale = "1 1 1";  
};  
datablock StaticShapeData(Planet4 : PlanetDataBlock) {  
    shapeFile = "art/shapes/planets/mars.dts";
    scale = "1 1 1";  
};  
datablock StaticShapeData(Planet5 : PlanetDataBlock) {  
    shapeFile = "art/shapes/planets/jupiter.dts";
    scale = "1 1 1";  
};  
datablock StaticShapeData(Planet6 : PlanetDataBlock) {  
    shapeFile = "art/shapes/planets/saturn.dts";
    scale = "1 1 1";  
};  
datablock StaticShapeData(Planet7 : PlanetDataBlock) {  
    shapeFile = "art/shapes/planets/uranus.dts";
    scale = "1 1 1";  
};  
datablock StaticShapeData(Planet8 : PlanetDataBlock) {  
    shapeFile = "art/shapes/planets/neptune.dts";
    scale = "1 1 1";  
};  

function spawnPlanets() {  
    for(%i = 0; %i < $numberOfPlanets; %i++)  
    {  
        echo(%i);
        %p = new StaticShape("planet_num" @ %i){  
            datablock = "Planet" @ %i;
        };
        %p.setName("Planet_" @ %i);
        %p.NickName = "planet #" @ %i;
        %trans = "-310 " @ (-200 - (5 * %i)) @ " 170";
        %p.setTransform(%trans);

        addMissionCleanup(%p);        
    }  
}

When I run "spawnPlanets();" from the console, I get the errors:
0
Can not find data block PLanet0;
Register object failed for object Planet_Num0 of class StaticShape.
.. (for each object)

I remember encountering a similar error a long time ago - any suggestions on what I'm doing wrong? I'm executing this within a server script.
#8
07/03/2009 (10:19 am)
Jesse, your hierarchy link was malformed.

Here:

tdn.garagegames.com/wiki/DTS/Scripting/Hierarchy

Also, one needs to login to TDN...
#9
07/03/2009 (12:26 pm)
Using your planets from the zip file, I found that there were no DTS files for the actual planets or the sun. I re-exported from Milkshape the 5 planets for which there were jpgs - mercury, mars, earth, venus & jupiter and removed the rest from your code. I execed planettest.cs containing your code from server/init.cs and ran the spawnplanets from onservercreated() in scripts/server/game.cs

That still didn't work, so then I moved the exec call out to one of our modules (not reflected in the GG scripts), where the datablocks get loaded in a call that is nestled about 3 layers in from onServerCreated, and then I called spawnPlanets in onServerCreated(), and that worked - all planets had jupiter texture, since no ifl was done.

Also, addMissionCleanup didn't work here - but we do our own handling of these things, so I didn't dig into that.
#10
07/03/2009 (12:37 pm)
Thanks much, Ken (PS - I have both of your books (though unfortunately left them at work, or would be looking more of this stuff up)).

So I think you're saying that the datablocks need to be created at a different time (before onServerCreated?), and then the spawnPlanets should be called later?
#11
07/03/2009 (12:53 pm)
Okay, went a little bit farther - this is more in conformance with the new way of doing things (NWODT):

I cut the datablock defs out of the code and put them in a file called plantdb.cs and dropped that file into art/datablocks, then added an exec for it into art/datablocks/datablockExec.cs.

I kept the function def & global variable (changed to 5 from 8) in planettest.cs, and dropped it into scripts/server and add an exec for it in scriptExec.cs. I left the spawnPlanets call in onServerCreated, and hey presto, still works.
#12
07/03/2009 (12:57 pm)
Hi Jay, yeah, essentially that's it. The NWODT tidies that up so that it makes more sense - keep your art asset datablocks in the art tree, and the rest of your script code in the trees where they are used.
#13
07/03/2009 (1:03 pm)
Excellent, and thanks!

Once I put all of the datablocks in the /My Projects/<proj>/game/art/datablocks/ directory, everything worked!

Did I miss that in the manual? Any chance that someone is working on better error messages for the TorqueScript compiler? That seems to be the weakest part of the entire tool.

Any other NWODT tricks that I need to watch out for?

Happy Canada Day/4th of July!
#14
07/03/2009 (1:32 pm)
Oh yeah, lotsa NWODT in the new T3D book :-)
#15
07/03/2009 (1:47 pm)
In that case, I'll buy two copies!
#16
07/03/2009 (5:42 pm)
new? T3d book?
#17
07/04/2009 (7:12 am)
3D Game Programming All In One, 3rd Edition

...which is T3D-centric.
#18
07/06/2009 (4:44 am)
Price range? May I put in a request?
1) Attach the game engine to a database like MYSQL or SQLLIGHT and use it.

2) Create basic class in C++ for a RTS type object like the AI you control and pathfinding.

3) Create a shapebased class for basic MMORPG thats light weight no need for all those bells and whistles.

I've read many if not all of the Torque programming books and they are not very informative about how to really use C++ code to improve your game. They are mostly about scripting and game concept and design.

Thank you again for your time Ken!