Game Development Community

Mount images on images (updated for T3D 1.1)

by Daniel Buckmaster · in Torque 3D Professional · 08/15/2011 (1:39 am) · 1 replies

I've updated this resource for T3D 1.1 after a few requests. I've no time to write a proper resource, but here's a code dump ;P. I've ifdef'd all the changes, so you need to define TORQUE_RES_MOUNTIMAGEIMAGE in torqueConfig.h to activate it. Syntax is:
%wpnSlot = 0;
%scopeSlot = 1;
%player.mountImage(WeaponImage, %wpnSlot);
%player.mountImageImage(ScopeImage, %scopeSlot, %wpnSlot);

In shapeBase.h:
struct ShapeBaseImageData: public GameBaseData {

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
   StringTableEntry imageMountNode;  ///< Name of node to mount on when we're mounted on an image
#endif

...

   struct MountedImage {

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
      S32 imageMountNode;
      S32 imageMountSlot;
#endif

...

   virtual bool mountImage(ShapeBaseImageData* image,U32 imageSlot,bool loaded, NetStringHandle &skinNameHandle);

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
   /// Mount an image (ShapeBaseImage) onto an already-mounted image
   /// @param   image   ShapeBaseImage to mount
   /// @param   imageSlot Image mount point
	/// @param   mountToSlot Mount this image onto the image already mounted in this slot
   /// @param   loaded    True if weapon is loaded (it assumes it's a weapon)
   /// @param   skinNameHandle   Skin name for object
   virtual bool mountImage(ShapeBaseImageData* image, U32 imageSlot, U32 mountToSlot, bool loaded, NetStringHandle &skinNameHandle);
#endif

In shapeBase.cpp:
//
            stream->writeFlag(isImageFiring(i));
#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
            if(stream->writeFlag(image.imageMountSlot != -1))
            {
               stream->writeInt(image.imageMountSlot,3);
               stream->writeInt(image.imageMountNode,6);
            }
#endif

...

            bool isFiring = stream->readFlag();

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
            if(stream->readFlag())
            {
               image.imageMountSlot = stream->readInt(3);
               image.imageMountNode = stream->readInt(6);
            }
#endif

...

DefineEngineMethod( ShapeBase, mountImage, bool,
   ...
}

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
DefineEngineMethod( ShapeBase, mountImageImage, bool,
   ( ShapeBaseImageData* image, S32 slot, S32 mountToSlot, bool loaded, const char* skinTag ), ( true, "" ),
   "@brief Mount a new Image.nn"

   "@param image the Image to mountn"
   "@param slot Image slot to mount into (valid range is 0 - 3)n"
   "@param mountToSlot Image slot to mount onto (valid range is 0 - 3)n"
   "@param loaded initial loaded state for the Imagen"
   "@param skinTag tagged string to reskin the mounted Imagen"
   "@return true if successful, false if failednn"

   "@tsexamplen"
   "%player.mountImage( PistolImage, 0 );n"
   "%player.mountImage( ScopeImage, 1, 0 );n"
   "@endtsexamplen"
   
   "@see mountImage()n"
   "@see unmountImage()n"
   "@see getMountedImage()n"
   "@see getPendingImage()n"
   "@see isImageMounted()n")
{
   if (image && slot >= 0 && slot < ShapeBase::MaxMountedImages) {

      NetStringHandle team;
      if (skinTag[0] == StringTagPrefixByte)
         team = NetStringHandle(U32(dAtoi(skinTag+1)));

      return object->mountImage( image, slot, mountToSlot, loaded, team );
   }
   return false;
}
#endif

In shapeImage.cpp:
ShapeBaseImageData::ShapeBaseImageData()
{

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
   imageMountNode = NULL;
#endif

...

void ShapeBaseImageData::initPersistFields()
{

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
   addField("imageMountNode", TypeString, Offset(imageMountNode, ShapeBaseImageData),
      "@brief Node name to mount this image to on other images.nn");
#endif

...

void ShapeBaseImageData::packData(BitStream* stream)
{

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
   stream->writeString(imageMountNode);
#endif

...

void ShapeBaseImageData::unpackData(BitStream* stream)
{

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
   imageMountNode = stream->readSTString();
#endif

...

ShapeBase::MountedImage::MountedImage()
{

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
   imageMountNode = -1;
   imageMountSlot = -1;
#endif

...

bool ShapeBase::mountImage(ShapeBaseImageData* imageData,U32 imageSlot,bool loaded,NetStringHandle &skinNameHandle)
{
   ...
}

#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
bool ShapeBase::mountImage(ShapeBaseImageData* imageData, U32 imageSlot, U32 mountToSlot, bool loaded, NetStringHandle &skinNameHandle)
{
   AssertFatal(imageSlot<MaxMountedImages,"Out of range image slot");
   AssertFatal(mountToSlot<MaxMountedImages,"Out of range mountTo slot");

   MountedImage& image = mMountedImageList[imageSlot];
   MountedImage& other = mMountedImageList[mountToSlot];
   if (other.dataBlock) {
      if(other.imageMountSlot == imageSlot)
      {
         Con::errorf("Warning: mountImage is trying to create a circular mount");
         return false;
      }
      if(imageData->imageMountNode)
         image.imageMountNode = other.dataBlock->shape->findNode(imageData->imageMountNode);
      else
         image.imageMountNode = -1;
   }
   else
      return false;
   image.imageMountSlot = mountToSlot;

   if (image.dataBlock) {
      if ((image.dataBlock == imageData) && (image.skinNameHandle == skinNameHandle)) {
         // Image already loaded
         image.nextImage = InvalidImagePtr;
         return true;
      }
   }
   //
   setImage(imageSlot,imageData,skinNameHandle,loaded);

   return true;
}
#endif

bool ShapeBase::unmountImage(U32 imageSlot)
{
   AssertFatal(imageSlot<MaxMountedImages,"Out of range image slot");

   bool returnValue = false;
   MountedImage& image = mMountedImageList[imageSlot];
   if (image.dataBlock)
   {
#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
      for(U32 i = 0; i < MaxMountedImages; i++)
      {
         if(mMountedImageList[i].imageMountSlot == imageSlot)
            unmountImage(i);
      }
		image.imageMountNode = -1;
		image.imageMountSlot = -1;
#endif
      NetStringHandle temp;
      setImage(imageSlot,0, temp);
      returnValue = true;
   }

   return returnValue;
}

...

      if (data.useEyeOffset && isFirstPerson()) {
         getEyeTransform(&nmat);
         mat->mul(nmat,data.eyeOffset);
      }
      else {
#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
         if(image.imageMountSlot != -1)
            getImageTransform(image.imageMountSlot, image.imageMountNode, &nmat);
         else
#endif
            getMountTransform( image.dataBlock->mountPoint, MatrixF::Identity, &nmat );
         mat->mul(nmat,data.mountTransform);
      }

...

      if ( !noEyeOffset && data.useEyeOffset && isFirstPerson() ) 
      {
         getRenderEyeTransform(&nmat);
         mat->mul(nmat,data.eyeOffset);
      }
      else 
      {
#ifdef TORQUE_RES_MOUNTIMAGEIMAGE
         if(image.imageMountSlot != -1)
            getRenderImageTransform(image.imageMountSlot, image.imageMountNode, &nmat);
			else
#endif
            getRenderMountTransform( 0.0f, data.mountPoint, MatrixF::Identity, &nmat );
         mat->mul(nmat,data.mountTransform);
      }

About the author

Studying mechatronic engineering and computer science at the University of Sydney. Game development is probably my most time-consuming hobby!


#1
08/16/2011 (9:25 am)
Thanks Daniel, I need something like this and will give it a try!