docs: public void onDrawFrame(float frameTime)
      {
          if (!isEnabled() || (getFloat("enabled") <= 0.0f) || (owner == null)) { return; }
          Matrix4f worldmtx = owner.getTransform().getModelMatrix4f();
          boolean changed = mChanged.getAndSet(false);
  
          mNewDir.x = 0.0f;
          mNewDir.y = 0.0f;
          mNewDir.z = -1.0f;
          worldmtx.getTranslation(mNewPos);
          worldmtx.mul(mLightRot);
          worldmtx.transformDirection(mNewDir);
          mNewDir.normalize();
          if ((mOldDir.x != mNewDir.x) || (mOldDir.y != mNewDir.y) || (mOldDir.z != mNewDir.z))
          {
              changed = true;
              setVec4("world_direction", mNewDir.x, mNewDir.y, mNewDir.z, 0);
              mOldDir.set(mNewDir);
              mChanged.set(false);
          }
          if ((mOldPos.x != mNewPos.x) || (mOldPos.y != mNewPos.y) || (mOldPos.z != mNewPos.z))
          {
              changed = true;
              setPosition(mNewPos.x, mNewPos.y, mNewPos.z);
              mOldPos.set(mNewPos);
              mChanged.set(false);
          }
          GVRShadowMap shadowMap = (GVRShadowMap) getComponent(GVRShadowMap.getComponentType());
          if ((shadowMap != null) && changed && shadowMap.isEnabled())
          {
              shadowMap.setPerspShadowMatrix(worldmtx, this);
          }
      }