Game Development Community

Popular camera resource problem T3D 1.2 and later

by 000 · in Torque 3D Beginner · 05/08/2014 (11:44 pm) · 2 replies

This popular camera resource and others like it have been posted and referenced a few times and I've run into a problem that I was hoping to open some discussion on.

From Torque 1.01 to Torque 1.1 Beta 3 the resource seems to work fine, but from 1.2 and onwards the player 'disappears' after walking a long enough distance. To demonstrate, here's a video:


This was taken with a vanilla T3D 1.2 full FPS template install, I've been able to replicate it with 3.0 and 3.5.

Of the resource being used I'm only using the camera part, which goes after the PreparePlayer in GameCore.cs:

// Make the camera side-facing
%client.setCameraObject(%client.camera);
%client.camera.setOrbitObject(%client.player, "0 0 " @ -mDegToRad(90), 15, 25, 25, false, "0 2 1", true);
%client.setFirstPerson(false);

I also used the other resources code, which is similar and provides the same results.

The player can still be moved it looks like, as I can move them in and out of this area.

The resources are a few years old and at the time everything worked fine, but something 1.2 and later happened that has caused this. I've been racking my brain but can't seem to come with any plausible solutions, anyone have any suggestions?

It'd be nice not to have to use a scripting option for the camera and have a way to control the rotation of the 'cam' node that's triggered for camera view in 3rd person. That way you can rotate it where you'd like it to point: side, over the shoulder, top down.

#1
07/11/2015 (10:23 pm)
A fix has been posted over at the Torque3d.org forums:

forums.torque3d.org/viewtopic.php?f=10&t=287#p2410

Thanks to TorqueFan, Adam Beer and Ivan Mandzhukov.

In camera.cpp find the processTick(). Within this function, replace the isMounted() bit with:
if (isMounted())
   {
      MatrixF mat;
      VectorF rotVec(0, 0, 0);

      if (move)
      {
         rotVec.x = move->pitch;
         rotVec.z = move->yaw;

         mRot.x += rotVec.x;
         mRot.z += rotVec.z;
      }

      MatrixF xRot, zRot, fmat;
      xRot.set(EulerF(rotVec.x, 0, 0));
      zRot.set(EulerF(0, 0, rotVec.z));

      // let's combine the euler rotation
      fmat.mul(zRot, xRot);

      // this will pull the transform and translate to world space
      // we need only the world position,we discard rotation values
      mMount.object->getMountTransform(mMount.node, mMount.xfm, &mat);

      Point3F position;
      mat.getColumn(3, &position);
      fmat.setColumn(3, position);
      Parent::setTransform(fmat);
      updateContainer();
      return;
   }

Next up, in camera.cpp find the interpolateTick(). Within this function, replace the isMounted() bit with:

if (isMounted())
   {
      MatrixF mat;
      Point3F rot = mDelta.rot + mDelta.rotVec * dt;
      MatrixF xRot, zRot, fmat;
      xRot.set(EulerF(rot.x, 0, 0));
      zRot.set(EulerF(0, 0, rot.z));

      // let's combine the euler rotation
      fmat.mul(zRot, xRot);

      // this will pull the transform and translate to world space
      // we need only the world position,we discard rotation values
      mMount.object->getRenderMountTransform(dt, mMount.node, mMount.xfm, &mat);

      Point3F position;
      mat.getColumn(3, &position);
      fmat.setColumn(3, position);
      Parent::setRenderTransform(fmat);
      return;
   }

Quote:
This solves the wacky transform when setting the camera to orbitObject mode and then mounting it to the Player. So this allows the camera to be mounted in a useful way. What this doesn't do is allow the camera to be mounted properly to any designated node. The node name declared in the mount(%target, %node) function could just as well be named "Tom's Cat". The camera will always be mounted to what appears to be the Player's root node. This should be only a small inconvenience given the optional transform settings for the mount() function, although I hadn't tested this to be sure it is indeed applying the optional transform.
#2
07/27/2015 (9:13 pm)
Call this at the end of GameCore::spawnPlayer

%client.setFirstPerson(false);   
   %client.setCameraObject(%client.camera);
   %client.camera.setOrbitObject(%client.player, "0 0 0", 10, 20, 20, false, "0 0 0", false);
   %client.camera.camDist = 10;

   %player.mountObject(%client.camera, "cam");