Game Development Community

Render Issue With Animated (Spinning) Spot Lights?

by Chad Hall · in Torque 3D Beginner · 08/04/2013 (6:58 am) · 2 replies

Hey everyone, I'm not sure if this is a known bug (I can't find it mentioned anywhere) or if I'm missing something obvious. When I add a spot light to a scene and set it to use the spinning animation, when the player is at a certain position or looking at a certain angle the light no longer renders when it should. When you move or rotate the camera just a bit more it starts rendering again.

I've had a friend confirm the issue as well. I've also had it occur on my own heavily modified source as well as vanilla T3D 3.0 and T3D 2.0. The issue occurs with both the player camera and the free-moving camera. Also with both the stock actor model and my own. It would seem the issue is with Torque itself but since I can't find it mentioned anywhere I figured I'd post about it.

To recreate the issue:

Add a spot light, set it to spin, and set it's position to "0 0 1".
Set your player transform to "-0.569054 -0.836059 0.0202708 0 0 1 2.71198".

That scenario causes the light to stop rendering for myself.

#1
08/14/2013 (3:41 am)
Surprised this didn't get any responses. Anyway, I'm super busy working on other stuff but finally took some time to try digging into this a bit deeper. I've tracked the problem to lightManager.cpp at line 228:

if ( staticLighting || !frustum )
   {
      // We're processing static lighting or want all the lights
      // in the container registerd...  so no culling.
      getSceneManager()->getContainer()->findObjectList( lightMask, &activeLights );
   }
   else
   {
      // Cull the lights using the frustum.
      LINE 228 -> getSceneManager()->getContainer()->findObjectList( *frustum, lightMask, &activeLights );

      // Store the culling position for sun placement
      // later... see setSpecialLight.
      mCullPos = frustum->getPosition();

If "getSceneManager()->getContainer()->findObjectList( lightMask, &activeLights );" is used instead then everything will work fine. I'm assuming the issue is kind of what what I expected from the beginning; looking into the LightAnimData class a bit I'm assuming the rotation of the animation isn't taken into consideration when checking if the object is within the frustum. In other words, the object's bounding box never changes from the starting direction and therefore isn't detected.

I assume a solution would be to either make the bounds squared - extending to the full range of the light, or, somehow updating the bounds with the animated rotation. I'll try looking into this more later and see if I can come up with something solid, still trying to understand how everything works right now.
#2
08/21/2013 (4:11 pm)
So, I've come up with a quick fix for this issue that I think works well. Basically, in spotLight.cpp in "void SpotLight::_conformLights()" I replaced the bounds setting code with this:

// Update the bounds and scale to fit our spotlight.
   F32 radius = mRange * mSin( mDegToRad( mOuterConeAngle ) * 0.5f );

   // At least a temporary fix for spinning Spot Light objects. Expand the
   // bounding box of animated spot lights so they don't get culled too early.
   // ---
   Point3F objectScale(radius, mRange, radius);
   Point3F objectBoxMin(-1, 0, -1);
	
    if (mAnimationData)
   {
	 if (!strcmp(mAnimationData->getName(), "SpinLightAnim"))
	{
	 objectBoxMin.set(-1, -1, -1);
	 objectScale.set(mRange, mRange, mRange);
	}
   }
   // ---

   mObjBox.minExtents.set(objectBoxMin);
   mObjBox.maxExtents.set( 1, 1, 1 );
   mObjScale.set(objectScale);

   // Skip our transform... it just dirties mask bits.
   Parent::setTransform( mObjToWorld );

So, spot lights using spinning animations use fully-encompassing cube-shaped bounding boxes and therefore don't get culled when the light should still be within view. If I encounter any further issues with this I'll update. Would appreciate any input from anyone if I'm missing something with my fix.