Game Development Community

Mounting images on images

by Daniel Buckmaster · in Torque Game Engine · 06/09/2008 (10:48 am) · 8 replies

This is kind of a wacky idea, but I think it'd be beneficial.

The idea is to be able to mount an image on another, already mounted image. For example, bayonets and scopes could be attached to weapons dynamically. Maybe even secondary weapons - underslung grenade launchers, etc.

Why not model them into the image in the first place?
Basically, that'd require a ridiculous amount of waste and redundancy. Say I'm making a pretty basic wargame. I have a laser gun and a bullet gun, one scope, a bayonet and a fusion-bayonet.
If we're making a new image for each combination of equipment that could be mounted, that's 12 different meshes already. Plus, imagine scripts to switch between them...
So instead - model two guns, one scope and two bayonets, and mount the equipment to the guns.

What changes would be involved here? Mounting images is something I'm not faimilar with, and seems to be less transparent than mounting objects.
Mounted objects simply calculate their transform every tick based on the position of a node. That makes it easy to mountanother object on a mounted object.
However, images don't seem to work this way.
I'm guessing I'd need to modify ShapeImageRenderImage and ShapeBase::renderMountedImage. Add a member to SIRI to say whether it's rendering on the node of a mounted image, and hen simply use the MountedImage struct to keep track of which.
Then, of course, the transform-getters would need to be modified...

About the author

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


#1
06/09/2008 (11:46 am)
Some games require that kind of flexibility in their design.
#2
06/12/2008 (2:43 am)
I'd actually look at the hiding mesh resource. That lets you hide meshes on staticshapes and such, so I expect with a little work you could get this to work for an image slot too. I think it'd be a much cleaner solution than hacking up the image system.
#3
06/13/2008 (3:14 am)
Edward: I agree...

Nick: But then you still get the same problem - each weapon has to be modeled with all equipment included. It makes it very difficult to add new items, especially for modders.
For the record, I do have that resource 'installed', and it's great for characters.

EDIT: I think the solution is simpler than I thought. ShapeBase::renderMountedImages calls getRenderImageTransform to get the position to render the image, if I am reading the code right. So all that needs to be modified are the transform get functions.
#4
06/14/2008 (12:41 am)
It seems like getImageTransform is the only function I need to modify (and getRenderImageTransform), since all the other image transform getters are based on this function. I added two members to MountedImage, an imageMountSlot (U32, the slot of the image this image is mounted to) and imageMountNode (const char*, the node on the image that this image is mounted to).
Then in getImageTransform:
void ShapeBase::getImageTransform(U32 imageSlot,MatrixF* mat)
{
   // Image transform in world space
   MountedImage& image = mMountedImageList[imageSlot];
   if (image.dataBlock) {
      ShapeBaseImageData& data = *image.dataBlock;

      MatrixF nmat;
      if (data.useEyeOffset && isFirstPerson()) {
         getEyeTransform(&nmat);
         mat->mul(nmat,data.eyeOffset);
      }
      else {
		  //Amado mount points ->
         //getMountTransform(image.dataBlock->mountPoint,&nmat);
		  getMountTransform(image.mountPoint,&nmat);
		  //<- Amado
		 //Dan's mods ->
		 //If we're mounted to another image, use their node transform
         if(image.imageMountSlot != -1)
         {
            MatrixF rmat, smat;
            getImageTransform(image.imageMountSlot,image.imageMountNode,&rmat);
            smat.mul(nmat,rmat);
            mat->mul(smat,data.mountTransform);
         }
         else
         //<- Dan
            mat->mul(nmat,data.mountTransform);
      }
   }
   else
      *mat = mObjToWorld;
}
I'm really not sure about the matrix maths in there, but I'm pretty sure it's wrong.
The new mountImage code I wrote works - the image is being initialised with its datablock, and its imageMountSlot and imageMountNode are being set correctly. However, the image doesn't render. Does anyone know where in the code an image might be excluded from rendering?

Also, possibly unrelated, the value of imageMountNode seems to be getting random fish in it. Sometimes I stick a breakpoint in Player::processTick for a random checkup, and the string, which was set to "shuttle" when I mounted the image, shows up as "1" or ";". I've breakpointed all the places where imageMountNode is changed, and none of them give the wrong values.
#5
06/14/2008 (3:09 am)
Are you sure it's not rendering? Might just be somewhere else, like at the world origin.
It's an important difference so you're not looking in the wrong spot!
#6
06/14/2008 (7:31 am)
I thought of that, so I tried a getMuzzlePoint on the image that I didn't think was rendering. It seemed to return the right location (given that the crossbow doesn't have a muzzle node :P), somewhere near the player's mount node...
I also took a trip to the origin - nothing there. Though the image may be rendered in some random place that's not where I want it - I've done that before with matrix maths :P
#7
06/17/2008 (6:13 am)
Okay, I simplified my system somewhat to remove a lot of extraneous stuff. But they key idea is still the same: when rendering, simply render the image in a different place.
However, I think I've tracked the problem down to my matrix maths. Specifically, the problem is smat.mul(nmat,rmat); This line causes the matrix to fill with fish. I'm thinking that I know why, but I'll test and see...

EDIT
It works!
[Dieter Meier voice]Oh yeah![/voice]
img291.imageshack.us/img291/6084/mountimageimageworksad4.pngThere's Kork with a second crossbow mounted to his normal one, on the "shuttle" node (which explains the od transform, I hope...)