Game Development Community

Object Preview in MainMenu

by Stefan Beffy Moises · in Torque Game Engine · 03/24/2002 (11:36 pm) · 32 replies

Hi,
I'm playing around with Frank Bignones' GuiObjectView perso.wanadoo.fr/hysteria/docs/guiCtrls.htm, and it works very well in-game (e.g. in Spocks InventoryManager), but I get this error if I try to use it from the MainMenuGui (that is, before the objects are loaded, ...)

Error: attempt to load a version 184 dts-shape, can currently only load version
24 and before.

If I try to load the same object AFTER the game/level/mission has loaded, it works just fine...
any idea how to get it to work in the MainMenu?
Do I have to execute some default scripts before it works? I'm trying to implement some type of player selection, especially for the Racing Mod (choose between car or tank,...)
Thanx!!!
Page «Previous 1 2
#1
03/24/2002 (11:45 pm)
If you can wait for a few more days (almost a week) I can promise you that this months reSource in the GG Community Newsletter will give you a gui control that not only displays models, but will allow easy changing of skins, rotation and zoom, as well as animation.

I don't want to see someone stressing over this when it's being wrapped up over here. I can't give it out just yet (i wanna keep it exclusive for the newsletter) but hopefully you'll be willing to wait a bit for it :)

I'm debating on whether or not to include a "select menu" already scripted since most people only have one model and skin on their computer, so I'd have to provide the models and skins in order to get it working correctly.

The syntax used in the control is very simple to figure out, so I might just explain how to do it and leave the actual coded example of a menu using the control up to the user.
#2
03/25/2002 (12:47 am)
I do not know why you have that error. BTW, this GUI object is my first contribution to Torque (aka V12 at that time and it might by quite buggy!!!). I have a new release of it that we use at the moment, I need to take some times to write a new tuts for it.

BTW, Matt's one might be more stable than mine.
#3
03/25/2002 (12:49 am)
Cool!! Another newsletter!
I'm really looking forward to it, the first one was great!
Especially to the tutorial you mentioned, of course...:-)
So are you providing some testmodels and stuff for it, or just some code snippets? Do you use the ObjectView code I mentionend or do you provide your own stuff?

But anyhow, I'd like to continue working on "my own", just because it bugs me what the problem might be... :-(
So any help would be appreciated!!
#4
03/25/2002 (12:59 am)
Frank-
thanks for the reply! Although you're code may be "old", I think it works quite well in the actual HEAD! :-)
The error is very strange indeed, because it works while in a running game... so it shouldn't be a general problem.
I think I'll just play around with it some more, maybe I can track it down... if not, all I have to do is wait 'til next week ... :-))
#5
03/25/2002 (9:54 am)
It just won't work... I always get this error when trying to add it to some start gui, e.g. mainMenuGui.gui ... any idea? Anybody?
And where does this error come from?? I can't find it anywhere in the code...?!
#6
03/25/2002 (10:06 am)
Errm, don't ask me why, but it's working now... what the heck is going on here...?! :-)
Anyhow, thanks for the help!!
#7
03/25/2002 (2:30 pm)
Yippeee, works great now, I can preview all my missions and players/vehicles/... now in one GUI (which will definitely be changed graphics-wise ;-) - but it works! :-)
Thanks for the code, Frank!
privat.schlund.de/b/beffy/pics/tork/beffy_3d_landscape_player_prev3.jpg
#8
03/25/2002 (2:42 pm)
You're welcome ;)
#9
03/25/2002 (3:39 pm)
care to share the resolution?
#10
03/25/2002 (11:02 pm)
You mean the resolution why it didn't work at first and now it does?? I've got no clue, but maybe it was only a problem of not finding the *.dts files... not sure about that...
Or do you mean sharing the code? Basically it's Franks' object view code, expanded with some script functions and packed into a single GUI window... if anyone is interested, I could write a little tut on how I've integrated it (or post my script files)...?
#11
03/25/2002 (11:58 pm)
oh ,using the link at the top,,,looks great
#12
03/26/2002 (12:26 am)
Yep, just be careful NOT to replace the files terrData.cc & terrData.h with the ones provided by Frank, they are not compatible with the latest Torque releases...
simply look for the one function he added to the class (can't remeber the name and I'm not at home right now) and add these parts to your own files...
and the line "data/object/plane/myplane.dts" should read "fps/data/..." to work properly (at least for me...)
:-)
#13
03/26/2002 (2:13 am)
yes , i am interested in the way you did it,i will wait till you do a lil tut if your going to,,,thanks
#14
03/28/2002 (2:25 pm)
Sorry, didn't have very much time within the last days..
anyhow, if you're still interested and can't wait for the next newsletter (it will handle this topic extensively, it seems!), here's how I did it:
STEP 1:
Download Franks zip file from perso.wanadoo.fr/hysteria/docs/guiCtrls.htm

STEP 2:
Add the additional files to your engine code:
- guiObjectView.cc & guiObjectView.h : place them in your game directory (i.e, /engine/game)
- guiTerView.cc & guiTerView.h : place them in your game directory (i.e, /engine/game)

STEP 3:
Backup your resManager.cc & resManager.h files and replace these two with the ones provided by Frank
(they still work with the latest HEAD)

STEP 4:
DO NOT replace your terrData.cc & terrData.h files like he mentioned in the tutorial - they seem to be outdated and don't work in the latest HEAD!!
Instead, add this function to terrData.cc:

bool TerrainBlock::addToClientGraph()
{
   setPosition(Point3F(-squareSize * (BlockSize >> 1), -squareSize * (BlockSize >> 1), 0));
   MaterialPropertyMap* pMatMap = static_cast<MaterialPropertyMap*>(Sim::findObject("MaterialPropertyMap"));
   StringTableEntry fn = mMaterialFileName[0];
   if(!dStrncmp(fn, "terrain.", 8))
      fn += 8;
   char nameBuff[512];
   dStrcpy(nameBuff, mTerrFileName);
   char *p = dStrrchr(nameBuff, '/');
   if (p) p++;
   else p = nameBuff;
   dStrcat(p,fn); 
   mMPMIndex[0] = pMatMap->getIndexFromName(nameBuff);
   
   mObjBox.min.set(-1e8, -1e8, -1e8);
   mObjBox.max.set( 1e8,  1e8,  1e8);
   resetWorldBox();
   setRenderTransform(mObjToWorld);

      if(mDetailTextureName && mDetailTextureName[0]) 
         mDetailTextureHandle = TextureHandle(mDetailTextureName, DetailTexture);
      
      lightMap = new GBitmap(LightmapSize, LightmapSize, false, GBitmap::RGB5551);

      if (!buildMaterialMap())
         return false;

      mTextureCallbackKey = TextureManager::registerEventCallback(terrainTextureEventCB, U32(this));

      mDynLightTexture = TextureHandle("special/lightFalloffMono", BitmapTexture, true);

      if (dglDoesSupportVertexBuffer())
         mVertexBuffer = glAllocateVertexBufferEXT(VertexBufferSize,GL_V12MTVFMT_EXT,true);
      else
         mVertexBuffer = -1;

   if(!unpackEmptySquares())
      return(false);

   return true;
}

I've added it just before void TerrainBlock::onRemove().

STEP 5:
Add this piece in terrData.h

public:
		bool addToClientGraph();

e.g. right after
void unpackUpdate(NetConnection *, BitStream *stream);

STEP 6:
compile your engine (clean build would be a good thing :-)

STEP 7:
Now for the scripting, I've put all the script for the GUI in one file named "terrainPreviewGui.gui", and added
exec("./ui/terrainPreviewGui.gui");
to fps/client/init.cs.
Then I call it from mainMenuGui.cs instead of the normal startMissionGui:

//command = "Canvas.setContent(startMissionGui);";
command = "Canvas.setContent(terrainPreviewGui);";

STEP 8:
In order to switch players/cars in a mod-specific way, I set a global variable in this new GUI file named
"$playerCSFile" and in the "game.cs" file of the actual mod I call:
//exec("./player.cs");
exec($playerCSFile);

or, for the car mod
//exec("./car.cs");
exec($playerCSFile);

respectively.

Furthermore, a variable $currentUserMod is set in "example/main.cs", which simply saves the recent mod.
I use it in terrainPreviewGui to set the paths to search for terrain and dts files:
(starting around line 62)
case "-mod":
         $argUsed[$i]++;
         if ($hasNextArg)
         {
            // save mod for global use - beffy 03/24/02
            $currentUserMod = $nextArg;

So, now here is the complete "terrainPreviewGui.gui" code (should be almost self explanatory):
// TerrainPreviewGUI by beffy, 03/23/2002
new GuiChunkedBitmapCtrl(TerrainPreviewGui) {
   profile = "GuiDefaultProfile";
   horizSizing = "right";
   vertSizing = "bottom";
   position = "0 0";
   extent = "780 580";
   minExtent = "8 8";
   visible = "1";
   helpTag = "0";

   new GuiControl() {
      profile = "GuiWindowProfile";
      horizSizing = "center";
      vertSizing = "center";
      position = "60 74";
      extent = "710 400";
      minExtent = "8 8";
      visible = "1";
      helpTag = "0";


      new GuiButtonCtrl(PrevModelButton) {
         profile = "GuiButtonProfile";
         horizSizing = "right";
         vertSizing = "top";
         position = "495 310";
         extent = "80 23";
         minExtent = "8 8";
         visible = "0";
         command = "TerrainPreviewGui::prevModel();";
         helpTag = "1";
         text = "<< Back";
      };
      new GuiButtonCtrl(NextModelButton) {
         profile = "GuiButtonProfile";
         horizSizing = "right";
         vertSizing = "top";
         position = "590 310";
         extent = "80 23";
         minExtent = "8 8";
         visible = "1";
         command = "TerrainPreviewGui::nextModel();";
         helpTag = "0";
         text = "Next >>";
      };
      new GuiTextCtrl(PlayerSelectTextCtrl) {
         profile = "GuiTextProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "485 25";
         extent = "88 20";
         minExtent = "8 8";
         visible = "1";
         text = "Select Model:";
         helpTag = "0";
         maxLength = "255";
      };
      // place to render the selected item
      new GuiObjectView(ToRKDisplayWindow) {
         profile = "GuiDefaultProfile";
         horizSizing = "relative";
         vertSizing = "relative";
         position = "485 64";
         extent = "230 220";
         minExtent = "8 8";
         visible = "1";
         helpTag = "0";
      };


      new GuiTerView(MM_ShowTerrain) {
         profile = "GuiButtonProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "210 93";
         extent = "240 240";
         minExtent = "8 8";
         visible = "1";
         modal = "0";
         helpTag = "0";
      };

      new GuiTextCtrl(MissionTextCtrl) {
         profile = "GuiTextProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "210 4";
         extent = "88 20";
         minExtent = "8 8";
         visible = "1";
         helpTag = "0";
         maxLength = "255";
      };
      new GuiTextCtrl(TerrainTextCtrl) {
         profile = "GuiTextProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "210 25";
         extent = "88 20";
         minExtent = "8 8";
         visible = "1";
         helpTag = "0";
         maxLength = "255";
      };

      new GuiButtonCtrl() {
         profile = "GuiButtonProfile";
         horizSizing = "right";
         vertSizing = "top";
         position = "10 184";
         extent = "127 23";
         minExtent = "8 8";
         visible = "1";
         command = "TerrainPreviewGui::StartMission();";
         helpTag = "0";
         text = "Go!";
      };

      new GuiButtonCtrl() {
         profile = "GuiButtonProfile";
         horizSizing = "right";
         vertSizing = "top";
         position = "10 212";
         extent = "127 23";
         minExtent = "8 8";
         visible = "1";
         //command = "TerrainPreviewGui::selectNextTerrain();";
         command = "TerrainPreviewGui::previewTerrain();";
         helpTag = "0";
         text = "Preview";
      };

      new GuiButtonCtrl() {
         profile = "GuiButtonProfile";
         horizSizing = "right";
         vertSizing = "top";
         position = "10 240";
         extent = "127 23";
         minExtent = "8 8";
         visible = "1";
         command = "Canvas.getContent().exit();";
         helpTag = "0";
         text = "<< Back";
      };
      new GuiCheckBoxCtrl(ML_isMultiplayer) {
         profile = "GuiCheckBoxProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "12 303";
         extent = "147 23";
         minExtent = "8 8";
         visible = "1";
         variable = "pref::HostMultiPlayer";
         helpTag = "0";
         text = "Multiplayer Mission";
         maxLength = "255";
      };
      new GuiTextEditCtrl() {
         profile = "GuiTextEditProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "12 30";
         extent = "164 16";
         minExtent = "8 8";
         visible = "1";
         variable = "pref::Player::Name";
         helpTag = "0";
         maxLength = "255";
         historySize = "0";
         password = "0";
         tabComplete = "0";
      };
      new GuiTextCtrl() {
         profile = "GuiTextProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "12 11";
         extent = "79 20";
         minExtent = "8 8";
         visible = "1";
         helpTag = "0";
         text = "Player Name:";
         maxLength = "255";
      };

      new GuiScrollCtrl() {
         profile = "GuiScrollProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "12 55";
         extent = "164 100";
         minExtent = "8 8";
         visible = "1";
         helpTag = "0";
         willFirstRespond = "1";
         hScrollBar = "dynamic";
         vScrollBar = "alwaysOn";
         constantThumbHeight = "0";
         defaultLineHeight = "15";
         childMargin = "0 0";

         new GuiTextListCtrl(ToRK_missionList) {
            profile = "GuiTextArrayProfile";
            horizSizing = "right";
            vertSizing = "bottom";
            position = "0 0";
            extent = "150 40";
            minExtent = "8 8";
            visible = "1";
            helpTag = "0";
            enumerate = "0";
            resizeCell = "1";
            columns = "0";
            fitParentWidth = "1";
            clipColumnText = "0";
            noDuplicates = "false";
         };
      };
   };
};
//--- OBJECT WRITE END ---

//----------------------------------------
function TerrainPreviewGui::onWake()
{
   //reset vars
   $numDTS = 0;
   $currentDTS = 0;
   $playerCSFile = "";
   $currTerrainId = 0;
   $terrCounter = 0;
   // clear Gui elements
   ToRK_missionList.clear();
   ToRKDisplayWindow.setEmpty();
   MM_ShowTerrain.detachTerrain();
   // search *.ter files and init the mission list
   TerrainPreviewGui::loadTerrains();
   TerrainPreviewGui::loadPlayerShapes($currentUserMod);
   // display first model in array
   TerrainPreviewGui::displayDTSItem();
}

//----------------------------------------
function TerrainPreviewGui::cancel(%this)
{
}

//----------------------------------------
function TerrainPreviewGui::exit(%this)
{
   // cleanup
   MM_ShowTerrain.detachTerrain();
   ToRKDisplayWindow.setEmpty();
   Canvas.setContent(mainMenuGui);
}

//--------------------------------------------------------------------
//  Search *.ter files, fill arrays and display all missions in list
//--------------------------------------------------------------------
function TerrainPreviewGui::loadTerrains()
{
   //$currentUserMod is set in "example/main.cs"...
   %filespec = $currentUserMod @ "/data" @ "/*.ter";
   %missionPath = $currentUserMod @ "/data/missions";
   // a little hack to get the mod directory
   //%delpos = strpos($Client::MissionFileSpec, "/*");
   //%modDir = getSubStr($Client::MissionFileSpec, 0, %delpos);

   for(%file = findFirstFile(%filespec); %file !$= ""; %file = findNextFile(%filespec))
   {
      // ignore CVS folder...
      if (strStr(%file, "CVS/") == -1)
      {
         //echo("count: " @ getFileCount("*.ter"));
         $terrFiles[$terrCounter] = filePath(%file) @ "/" @ fileName(%file);
         $missionFiles[$terrCounter] = %missionPath @ "/" @ fileBase(%file) @ ".mis";
         echo("File " @ $terrCounter @ ": " @ $terrFiles[$terrCounter]);
         ToRK_missionList.addRow($terrCounter, getMissionDisplayName($missionFiles[$terrCounter]) @ "\t" @ %file );
         $terrCounter++;
      }
   }
   ToRK_missionList.sort(0);
   ToRK_missionList.setSelectedRow(0);
   ToRK_missionList.scrollVisible(0);
}

//--------------------------------------------------------------------
//  Preview selected mission terrain
//--------------------------------------------------------------------
function TerrainPreviewGui::previewTerrain()
{
   %id = ToRK_missionList.getSelectedId();
   TerrainTextCtrl.setText("Terrain file: " @ $terrFiles[%id]);
   MissionTextCtrl.setText("Mission: " @ getMissionDisplayName($missionFiles[%id]));
   MM_ShowTerrain.detachTerrain();
   MM_ShowTerrain.attachTerrain($terrFiles[%id]);
}

//--------------------------------------------------------------------
//  Return the next terrain in cycle
//--------------------------------------------------------------------
function TerrainPreviewGui::cycleTerrains()
{
   if($currTerrainId++ == $terrCounter)
   {
      $currTerrainId = 0;
   }
   TerrainTextCtrl.setText("Terrain file: " @ $terrFiles[$currTerrainId]);
   MissionTextCtrl.setText("Mission: " @ getMissionDisplayName($missionFiles[$currTerrainId]));
   return $terrFiles[$currTerrainId];
}
//--------------------------------------------------------------------
//  Select the next terrain in cycle
//--------------------------------------------------------------------
function TerrainPreviewGui::selectNextTerrain()
{
   MM_ShowTerrain.detachTerrain();
   MM_ShowTerrain.attachTerrain(TerrainPreviewGui::cycleTerrains());
}
//--------------------------------------------------------------------
//  Start the selected mission
//--------------------------------------------------------------------
function TerrainPreviewGui::StartMission()
{
   MM_ShowTerrain.detachTerrain();
   %mission = $missionFiles[ToRK_missionList.getSelectedId()];
   // used in game.cs to load the appropriate player script
   $playerCSFile = $playerFiles[$currentDTS];

   if ($pref::HostMultiPlayer)
      %serverType = "MultiPlayer";
   else
      %serverType = "SinglePlayer";

   createServer(%serverType, %mission);
   localConnect($pref::Player::Name);
}
//--------------------------------------------------------------------
//  Parse mission files for mission name
//--------------------------------------------------------------------
function getMissionDisplayName( %missionFile )
{
   %file = new FileObject();

   %MissionInfoObject = "";

   if ( %file.openForRead( %missionFile ) ) {
		%inInfoBlock = false;

		while ( !%file.isEOF() ) {
			%line = %file.readLine();
			%line = trim( %line );

			if( %line $= "new ScriptObject(MissionInfo) {" )
				%inInfoBlock = true;
			else if( %inInfoBlock && %line $= "};" ) {
				%inInfoBlock = false;
				%MissionInfoObject = %MissionInfoObject @ %line;
				break;
			}

			if( %inInfoBlock )
			   %MissionInfoObject = %MissionInfoObject @ %line @ " ";
		}

		%file.close();
	}
	%MissionInfoObject = "%MissionInfoObject = " @ %MissionInfoObject;
	eval( %MissionInfoObject );

   %file.delete();

   if( %MissionInfoObject.name !$= "" )
      return %MissionInfoObject.name;
   else
      return fileBase(%missionFile);
}


//--------------------------------------------------------------------
//  initialize arrays with shape- and scriptpaths
//--------------------------------------------------------------------
function TerrainPreviewGui::loadPlayerShapes(%mod)
{
   if(%mod $= "fps")
   {
      $playerShapes[0] = %mod @ "/data/shapes/player/player.dts";
      $playerFiles[0] = %mod @ "/server/scripts/player.cs";
      $numDTS++;
   }
   else if(%mod $= "racing")
   {
      $playerShapes[0] = %mod @ "/data/shapes/tank/tank4wheel.dts";
      $playerFiles[0] = %mod @ "/server/scripts/tank4wheel.cs";
      $numDTS++;
      $playerShapes[1] = %mod @ "/data/shapes/tank/tank8wheel.dts";
      $playerFiles[1] = %mod @ "/server/scripts/tank8wheel.cs";
      $numDTS++;
      $playerShapes[2] = %mod @ "/data/shapes/car/car.dts";
      $playerFiles[2] = %mod @ "/server/scripts/car.cs";
      $numDTS++;
   }
}

//--------------------------------------------------------------------
//  display current *.dts
//--------------------------------------------------------------------
function TerrainPreviewGui::displayDTSItem()
{
   PrevModelButton.visible = "1";
   NextModelButton.visible = "1";
   ToRKDisplayWindow.setEmpty();
   %file = $playerShapes[$currentDTS];
   echo("Loading " @ %file);
   ToRKDisplayWindow.setModel(%file , "");
}


//--------------------------------------------------------------------
//  go back one dts
//--------------------------------------------------------------------
function TerrainPreviewGui::prevModel()
{
   if($currentDTS-- < 0)
   {
      $currentDTS = $numDTS-1;
   }
   echo($currentDTS);
   TerrainPreviewGui::displayDTSItem();
}

//--------------------------------------------------------------------
//  show next dts
//--------------------------------------------------------------------
function TerrainPreviewGui::nextModel()
{
   if($currentDTS++ >= $numDTS)
   {
      $currentDTS = 0;
   }
   echo($currentDTS);
   TerrainPreviewGui::displayDTSItem();
}

Here is a screenshot of it:
thesoulnomads.de/tork/gallery/beffy_3d_landscape_player_prev3.jpg

STEP 9: Preview, select and enjoy! :-)
Any questions? Don't ask me... (just kiddin' ;-))
#15
03/28/2002 (8:24 pm)
Drool...
#16
03/28/2002 (8:56 pm)
wow awesome, i will take a break from my map learning and learn this objectveiw stuff ,,,thanks :)

[edit] you been very kind to me with your knowledge :). Since i am learning to make new interior stuff i would be willing to make you some custom objects (if i can) to return the favor.
thanks [/edit]
#17
03/28/2002 (11:50 pm)
i get an error when i compile
//-------------------------------------
guiObjectView.obj : error LNK2001: unresolved external symbol "public: class ResourceObject * __thiscall ResManager::createResource(char const *)" (?createResource@ResManager@@QAEPAVResourceObject@@PBD@Z)

//------------------------------------
i will redoit when i get to work
#18
03/29/2002 (1:26 am)
Did you replace your resManager.* files with the ones provided in Frank's zip-file?
If you did and it still doesn't work, you could try the files provided by Spock here www.garagegames.com/uploaded/code/1962.objectviewcode.zip(but they should be the same as Franks' anyhow...) - these are the ones I used - because I integrated his inventory manager before I did this preview gui... give it a try, do another clean build and tell me what happened...
#19
03/29/2002 (2:18 am)
Yes, you're linker error is because you do not have the new method defined in the resManager.cc & .h files. BTW, even if you replace the files, sometimes compiler will not recompile it, so :
1. Clean your project (in vc6+ build/clean)
2. Compile it again.
#20
03/29/2002 (2:19 am)
yeah,i downloaded the latest head just tonight, and was very happy there were no errors when i compiled it,

i tried 3different zips including them two (dont know where i got the first one (hehe dummy me, after adding the 2 terVeiws to the project i get the same error with it also,)

so i ran the debug build for the frist time in ,,well forever and it says this

//-----------------------------
f:\1torque\engine\scenegraph\scenelighting.cc(1323) : error C2248: 'freeResource' : cannot access private member declared in class 'ResManager'
f:\1torque\engine\core\resmanager.h(257) : see declaration of 'freeResource'

f:\1torque\engine\scenegraph\scenelighting.cc(1365) : error C2248: 'freeResource' : cannot access private member declared in class 'ResManager'
f:\1torque\engine\core\resmanager.h(257) : see declaration of 'freeResource'

//-----------------------------------------


so i figger im missing somthing some where's since i never messd with the scenelighting.cc

i will go look over the "head" ResManager files and compare them to the one from the zip and see if i am missing somthing.

thanks

[edit] hmm ya, frank i always do a "clean" befor i compile, maybe my vc is acting up and needs to be reinstalled if i remember right i had this problem before, but i'll go play with it and see what happens. thanks [/edit]
Page «Previous 1 2