Game Development Community

[Beta 5 Bug] Camera Pokes Through Walls (w/ Fix)

by Ryan Mounts · in Torque 3D Professional · 09/10/2009 (7:10 pm) · 3 replies

This isn't really a bug; it's more of just an annoying issue. The problem is with the camera position validation code in Shapebase, whereby the 3rd person camera can get too close to objects, allowing it to "poke through" walls and such. Without going into an explanation of what's wrong with the code (for lack of time), here's my solution to the problem. I have still been able to get the "poke through" effect briefly under a couple of extreme circumstances, but it is much more robust than the code is now.

In "T3DshapeBase.cpp" find the "ShapeBase::getCameraTransform()" method, and change this:

// Make sure we don't extend the camera into anything solid
   Point3F ep = sp + vec + offset;
   disableCollision();
   if (isMounted())
      getObjectMount()->disableCollision();
   RayInfo collision;

   if (mContainer->castRay(sp, ep,
                           (0xFFFFFFFF & ~(WaterObjectType      |
                                           GameBaseObjectType   |
                                           DefaultObjectType)),
                           &collision) == true) {

      F32 vecLenSq = vec.lenSquared();
      F32 adj = (-mDot(vec, collision.normal) / vecLenSq) * 0.1;
      F32 newPos = getMax(0.0f, collision.t - adj);
      if (newPos == 0.0f)
         eye.getColumn(3,&ep);
      else
         ep = sp + offset + (vec * newPos);
   }

to this:

// Make sure we don't extend the camera into anything solid
   Point3F ep = sp + vec + offset;
   Point3F vecDir = vec/vec.len();                                     // Add
   disableCollision();
   if (isMounted())
      getObjectMount()->disableCollision();
   RayInfo collision;

   if (mContainer->castRay(sp, ep + vecDir,                            // Modify (+ vecDir)
                           (0xFFFFFFFF & ~(WaterObjectType      |
                                           GameBaseObjectType   |
                                           DefaultObjectType)),
                           &collision) == true) {

//      F32 vecLenSq = vec.lenSquared();                               // Remove
//      F32 adj = (-mDot(vec, collision.normal) / vecLenSq) * 0.1;     // Remove
//      F32 newPos = getMax(0.0f, collision.t - adj);                  // Remove
//      if (newPos == 0.0f)                                            // Remove
//         eye.getColumn(3,&ep);                                       // Remove
//      else                                                           // Remove
//        ep = sp + offset + (vec * newPos);                           // Remove

      F32 offset = 0.1f / mDot(-vecDir, collision.normal);             // Add
      Point3F a = collision.point - ep;                                // Add

      if(mDot(a, vecDir) > 0.0f)                                       // Add
      {                                                                // Add
         if(offset > a.len())                                          // Add
            ep = collision.point - vecDir * offset;                    // Add
      }                                                                // Add
      else                                                             // Add
         ep = collision.point - vecDir * offset;                       // Add
   }

#1
09/10/2009 (8:36 pm)
tryin this right now. Thanks so much for it.
#2
09/12/2009 (8:51 am)
Got it in.. yeah, it doesn't fall through terrain and big flat surfaces now. But with complex geometry it can bring camera in weird places, but it's much better now comparing to how it was.

Thanks for sharing Ryan!

Edit:
P.S. Actually, after some more testing I haven't noticed camera to "fall" through the surfaces at all, so I want to say: Vote for this to be included in stock T3D! :)
#3
09/12/2009 (8:36 pm)
Got my vote for adding to core base code.