Game Development Community

Scaling a mounted ShapeBaseImage

by Konrad Kiss · 07/02/2009 (3:40 pm) · 39 comments

To be able to set your weapon's scale without having to re-export it, do the following:

First, in shapeBase.h find (in the ShapeBaseImageData struct)
/// Maximum number of sounds this image can play at a time.
   /// Any value <= 0 indicates that it can play an infinite number of sounds.
   S32 maxConcurrentSounds;

and after that insert:
// >>>
   // custom mounted image scaling
   Point3F scale;
   // <<<

Next, in shapeImage.cpp, add to the ShapeBaseImageData constructor:
// >>>
   scale = Point3F(1,1,1);
   // <<<

Still in the same file, find ShapeBaseImageData::initPersistFields() and add at the end of the method:
// >>>
   addField("scale", TypePoint3F, Offset(scale, ShapeBaseImageData));
   // <<<

In the ShapeBaseImageData::packData method, add at the end:
// >>>
   mathWrite( *stream, scale );
   // <<<

In the ShapeBaseImageData::unpackData method, add at the end:
// >>>
   mathRead( *stream, &scale );
   // <<<


In shapeBase.cpp's ShapeBase::prepBatchRender find the following:
MatrixF mat;
         getRenderImageTransform(mountedImageIndex, &mat, state->isShadowPass());
         GFX->setWorldMatrix( mat );

         image.shapeInstance->animate();
         image.shapeInstance->render( rdata );

and replace with this:
MatrixF mat;
         getRenderImageTransform(mountedImageIndex, &mat, state->isShadowPass());
         GFX->setWorldMatrix( mat );

         image.shapeInstance->animate();
         // >>>
         MatrixF s(true);
         s.scale( image.dataBlock->scale );
         GFX->multWorld( s );
         // <<<
         image.shapeInstance->render( rdata );

Finally, some scripting: in your weapon's (or any other mounted image's) ShapeBaseImageData datablock, add a scale property (defaults to Point3F(1,1,1) if not set, which means no further scaling) and set it's value to the desired scale.

You're done, now you can scale any of your mounted objects. Tested only in Torque3D.

Update (07/30/2009): Updated the resource to make it networked.
Update (09/25/2009): Updated code to reflect changes to a getRenderImageTransform call from Beta 5.
Update (01/30/2010): For T3D 1.0.1, check out this post by Eikon Games.

About the author

Lead Developer at Bitgap Games (www.bitgap.com) currently working on Xenocell (www.xenocell.com) a massively multiplayer action strategy game based on Torque 3D technology.

Page«First 1 2 Next»
#21
10/19/2009 (7:51 am)
@Martin

Pray tell how would one modify the Player::renderMountedImage()?
Im not too bright when it comes to modifying the source.
#22
10/19/2009 (6:47 pm)
Works in T3D v1.0.1 with no problems at all - it even updates in realtime in the datablock editor (when the stock offset and rotation do not!).
I had to make the change inside Player::renderMountedImage() to get it to work and left the changes in ShapeBase::renderMountedImage() for good measure (not sure if that was required).

ShapeBase::renderMountedImage (in shapeBase.cpp) looks like this:
void ShapeBase::renderMountedImage( U32 imageSlot, TSRenderState &rstate )
{
   GFX->pushWorldMatrix();

   MatrixF mat;
   getRenderImageTransform(imageSlot, &mat, rstate.getSceneState()->isShadowPass());
   GFX->setWorldMatrix(mat);
   MountedImage& image = mMountedImageList[imageSlot];
   image.shapeInstance->animate();
   MatrixF s(true);
   s.scale(image.dataBlock->scale);
   GFX->multWorld(s);
   image.shapeInstance->render(rstate);

   GFX->popWorldMatrix();
}

...and the last few lines of Player::renderMountedImage() (in player.cpp) look like this:
else 
   {
      getRenderMountTransform(data.mountPoint,&nmat);
      world.mul(nmat,data.mountTransform);
   }

   GFX->setWorldMatrix( world );

   image.shapeInstance->animate();
   MatrixF s(true);
   s.scale(image.dataBlock->scale);
   GFX->multWorld(s);
   image.shapeInstance->render( rstate );

   GFX->popWorldMatrix();
}
#23
10/21/2009 (11:16 pm)
Thanks Eikon,

Works great.
#24
11/09/2009 (7:59 pm)
Anyone has run the code in the T3D v1.0.1?

I copied and pasted all codes and examined several times.

But still doesn't work.
#25
01/07/2010 (1:20 am)
In T3D v1.1Alpha,
ShapeBase::prepBatchRender has been changed to:
void ShapeBase::prepBatchRender(SceneState* state, S32 mountedImageIndex )
{
   // CHANGES IN HERE SHOULD BE DUPLICATED IN TSSTATIC!
   
   GFXTransformSaver saver;
   
   // Set up our TS render state. 
   TSRenderState rdata;
   rdata.setSceneState( state );
   if ( mCubeReflector.isEnabled() )
      rdata.setCubemap( mCubeReflector.getCubemap() );
   rdata.setFadeOverride( mFadeVal );

   if ( LIGHTMGR && !state->isShadowPass() )
      LIGHTMGR->setupLights( this, getWorldSphere() );

   if( mountedImageIndex != -1 )
   {
      MountedImage& image = mMountedImageList[mountedImageIndex];

      if( image.dataBlock && image.shapeInstance )
      {
         renderMountedImage( mountedImageIndex, rdata );
      }
   }
   else
   {
      MatrixF mat = getRenderTransform();
      mat.scale( mObjScale );
      GFX->setWorldMatrix( mat );

      if ( state->isDiffusePass() && mCubeReflector.isEnabled() && mCubeReflector.getOcclusionQuery() )
      {
         RenderPassManager *pass = state->getRenderPass();

         OccluderRenderInst *ri = pass->allocInst<OccluderRenderInst>();   

         ri->type = RenderPassManager::RIT_Occluder;
         ri->query = mCubeReflector.getOcclusionQuery();   
         mObjToWorld.mulP( mObjBox.getCenter(), &ri->position );
         ri->scale.set( mObjBox.getExtents() );
         ri->orientation = pass->allocUniqueXform( mObjToWorld );        
         ri->isSphere = false;
         state->getRenderPass()->addInst( ri );
      }

      mShapeInstance->animate();
		// >>>
		MatrixF s(true);
		s.scale( image.dataBlock->scale );
		GFX->multWorld( s );
		// <<<
      mShapeInstance->render( rdata );
   }
   
   if ( LIGHTMGR )
      LIGHTMGR->resetLights();
}

What I did was to throw in those 3 lines as indicated, however it seems most of the other functions have changed, so it's giving me errors. Any help would be appreciated, thanks! :)
#26
01/21/2010 (5:04 pm)
anyone got this working in 1.1a yet? If so can you post your changes?
#27
02/19/2010 (8:03 pm)
This also works in 1.1beta1 on single player. Although I didn't need Eikons player.cpp change, error on compile, so reverted back to existing stock player.cpp

Great resource thanks Konrad. Surprised it's not stock!
#28
02/20/2010 (7:42 am)
Spoke too soon! However In dedicated server on 1.1beta1. I'm getting the following error on the console: update TSShape loadprogress Unknown Command. It doesn't work on dedicated. Any ideas?
#29
02/20/2010 (8:34 am)
I just had this a few days ago. It's not related to this resource though. As far as I could tell, it's a problem with datablocks that use a dae file as a shape file (such as the default tree model). Try removing that tree from managedForestData.cs, see if that solves the problem for you.

I'm not at my dev pc right now, so can't say specifics. Let me know how that goes.
#30
02/20/2010 (8:55 am)
@Konrad - yeah, you're right - thanks for that! Never noticed it before. I'll let you know if dedicated server works, have you tested it on 1.1beta1 ?
#31
03/18/2010 (12:46 pm)
@S2P - I'm trying to get the crossbow scaled down for Gideon in 1.1B1 dedicated. Have you been able to get this to work?

#32
03/18/2010 (12:52 pm)
@Scot - I've not tried lately, just upgraded to AFX2.0 for T3D 1.1B1. I'll be trying this again over the weekend.
#33
03/19/2010 (8:54 am)
oh, AFX is updated now? Cool...yes, please let me know if you get this working in 1.1B, I'm anxious to scale down the crossbow and am sure it'll come in handy in the future if it doesn't get wrapped into the final release.
#34
03/23/2010 (12:06 pm)
@S2P - did you get a chance to play with scaling down weapons over the weekend?
#35
03/23/2010 (12:10 pm)
Fraid not, had some outstanding php and flash projects to get out of the way before I can get back into things. It'll be this week for sure.
#36
04/14/2010 (8:47 pm)
Hm... seems to be working...
#37
05/02/2010 (12:14 pm)
Hi

Got this working in T3D 1.0.1 with the following change.

ShapeBase::prepBatchRender changes quite considerably ... merely make the following change.

MountedImage& image = mMountedImageList[mountedImageIndex];

      if( image.dataBlock && image.shapeInstance )
      {

		  // >>>  	
		  MatrixF s(true);  
		  s.scale( image.dataBlock->scale );  
		  GFX->multWorld( s );  
		  // <<< 

         renderMountedImage( mountedImageIndex, rdata );

This puts the code in the correct context and works like a charm.

Hope this helps.
#38
12/12/2010 (4:28 am)
Edit: Got it working...thanks! Waited a year to finally tackle this.

Is there a simple way to make sure the bounding box scales with it? I've got a huge gun that I've scaled down to .125 of it's original size but in-game the bounding box is still the same.
#39
11/16/2011 (12:44 pm)
Thanks as always Konrad.
Working in T3D 1.1 Final.
Page«First 1 2 Next»