BackfaceCulling not working

  • On 11/06/2014 at 17:10, xxxxxxxx wrote:

    Thank you anyway, Scott.
    My "hand coded" solution seems to work fine and it is fast enough.
    I already included it in my "c4d_helpers.cpp" file ;-)

    Well, I only started coding in C++ a week ago and I already started coding some utilities for future plugins :-)

  • On 11/06/2014 at 19:02, xxxxxxxx wrote:

    It was bugging me why it didn't work properly in the non-orthographic views. So I kept working on it.
    And then I realized that what I was doing was getting the normal of the polygon in relation to the world...not the camera.

    This seems to give me the proper results using the BackfaceCulling() function:

    Bool SimplePlugin::Execute(BaseDocument *doc)  
      PolygonObject *obj = (PolygonObject* ) doc->GetActiveObject();  
      if (!obj) return FALSE;  
      if (!obj || obj->GetType() != Opolygon) return FALSE;  
      Vector *vadr = obj->GetPointW();  
      CPolygon poly = obj->GetPolygonW()[0];  
      Vector N = CalcFaceNormal(vadr, poly) * obj->GetMg();  
      BaseDraw *bd = doc->GetActiveBaseDraw();  
      BaseObject *camera = bd?bd->GetSceneCamera(doc) :NULL;  
      //Get the index#'s for the four points in the selected polygon  
      LONG A = poly.a;  
      LONG B = poly.b;  
      LONG C = poly.c;  
      LONG D = poly.d;  
      //Get the vector positions of the four polygon's points  
      Vector posa = vadr[A];  
      Vector posb = vadr[B];  
      Vector posc = vadr[C];  
      Vector posd = vadr[D];  
      Vector polyLocation = (vadr[A] + vadr[B] + vadr[C] + vadr[D]) / 4;  
      Vector midpoint = polyLocation * camera->GetMg();  
      Bool bf = bd->BackfaceCulling(N, midpoint);     //Checks if the polygon is being seen by the camera  
      return TRUE;   


    *Edit- Nope. Still not right.
     Maxon. Can you please provide a working example how to use the BackfaceCulling() method?

  • On 12/06/2014 at 00:06, xxxxxxxx wrote:


    BaseView::BackfaceCulling expects points and vectors in camera space.
    We have to respectively call BaseView::WC and BaseView::WC_V to convert points and vectors from world to camera space.
    Also note you can just pass the first polygon point as center point.

    Bool bf = bd->BackfaceCulling(bd->WC_V(N), bd->WC(posa));

  • On 12/06/2014 at 00:54, xxxxxxxx wrote:

    I used those transformations and it still messed up when the object was moved around.
    I started out with the face normal like this:

    N = CalcFaceNormal(pt_list, pol)*op_matrix;

    It needs to be in world coordinates first, right?

    Then I got the center coordinate (now I know I can use the first point), also in world coordinated, right?

    Then I tested for culling with:

    Bool bf=bd->BackfaceCulling(bd->WC_V(N),bd->WC(cp));

    and I just worked fine when the object was at the origin, not when I moved it around.

    p.s. It should be more clear in the SDK documentation that BackfaceCulling needs coordinates in camera space.

  • On 12/06/2014 at 02:21, xxxxxxxx wrote:

    The documentation is wrong. BackfaceCulling() returns true if a face isn't visible (face is occluded) and false if it's visible.

    Here's the code I've used:

    Bool MenuTest::Execute(BaseDocument* doc)
      BaseObject* op = doc->GetActiveObject();
      if (op==nullptr)
        return false;
      if (op->GetType()!=Opolygon)
        return false;
      PolygonObject* poly = ToPoly(op);
      if (!poly)
        return false;
      Matrix mg = poly->GetMg();
      const Vector* points = poly->GetPointR();
      const CPolygon* polygons = poly->GetPolygonR();
      Vector normal = mg.TransformVector(CalcFaceNormal(points, polygons[0]));
      BaseDraw* bd = doc->GetActiveBaseDraw();
      Int32 a = polygons[0].a;
      Int32 b = polygons[0].b;
      Int32 c = polygons[0].c;
      Int32 d = polygons[0].d;
      Vector posa = mg * points[a];
      Vector posb = mg * points[b];
      Vector posc = mg * points[c];
      Vector posd = mg * points[d];
      Bool bf = bd->BackfaceCulling(bd->WC_V(normal), bd->WC(posa));
      return true;

    Originally posted by xxxxxxxx

    p.s. It should be more clear in the SDK documentation that BackfaceCulling needs coordinates in camera space.

    Yes I'll add this information to BaseView::BackfaceCulling in the documentation and fix the returned Bool sentence.

  • On 12/06/2014 at 03:35, xxxxxxxx wrote:

    Thank you for the info, Yannick.
    I tried to implement your code but Xcode tells me that Matrix has no member named TransformVector.

  • On 12/06/2014 at 07:01, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Thank you for the info, Yannick.
    I tried to implement your code but Xcode tells me that Matrix has no member named TransformVector.

    Sorry I used the R15 SDK in my code example. If you use a pre-R15 you should be able to replace TransformVector with the * operator instead.
    But I don't think the normal has to be transformed to the object's space.

  • On 12/06/2014 at 07:57, xxxxxxxx wrote:

    Thanks Yannick. But it's still not working properly for me.
    I used this for R13: Vector normal = mg * (CalcFaceNormal(points, polygons[0]));

    Here's what I'm doing to test it:
    - Create a cube and make it editable
    - Make the polygon facing the camera(polygon[0])  a little smaller so it's easy to see when the object is rotated
    -Execute the plugin. The result is 0         //<--Working properly so far
    -Move the cube to (100, 100, -100)
    -execute the plugin. The result is still 0  //<--Still working properly
    -Rotate the cube to (180, 0, 0)
    -execute the plugin. The result is still 0  //<--Ouch! This is wrong.
    polygon[0] is now facing away from the camera. Yet it's still returning 0 as if it was facing the camera.

    Now here's the really freaky part.
    If I spin the camera around for a while without touching the object at all. I can eventually get a result of 1 again.
    And if I then re-set the camera to it's default position. Remembering that the result was zero for that before. The result stays at 1 and not 0.Wacko

    In other words. It's not consistent at all and seems to be extremely buggy.


  • On 12/06/2014 at 11:34, xxxxxxxx wrote:

    Never mind Yannick.
    I tried your code in R15 and it works. Maxon must have fixed some bugs since R13.

    I have some hand written code that works for BF culling in R13. But I was just curious to learn how to use the SDK's BackfaceCulling() function.
    It seems to be very buggy in R13 (and maybe R14?). But it seems to work fine in R15.


  • On 12/06/2014 at 12:09, xxxxxxxx wrote:

    I can confirm that it is still buggy in R14.

Log in to reply