BackfaceCulling not working



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

    I've never used the BackfaceCulling() function before. But since you brought it up. I took a crack at it.
    I haven't tried it out looping through several polygons yet. I'm just manually grabbing the first polygon and checking it's BF value. But so far it seems to be working as expected.

    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();  
      
      //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 * obj->GetMg();  
      Bool bf = bd->BackfaceCulling(N, midpoint);  
      GePrint(LongToString(bf));  
      
      EventAdd();  
      return TRUE;   
    }
    

    -ScottA



  • On 11/06/2014 at 16:40, xxxxxxxx wrote:

    It also works here, as long as the object is located at the origin.
    But, as soon as I move the object around, it seems to fail.



  • On 11/06/2014 at 16:51, xxxxxxxx wrote:

    It works for me even if I move/rotate the object around in the scene.
    But I just noticed that it only seems to work when in an orthographic camera views.
    Maybe the camera has to be set up somehow to use it with Parallel and Perspective views?

    I'm afraid I can't be of much help for that.

    -ScottA



  • 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  
      GePrint(LongToString(bf));  
      
      
      EventAdd();  
      return TRUE;   
    }
    

    -ScottA

    *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:

    Hi,

    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));
      GePrint(String::IntToString(bf));
      
      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.

    -ScottA



  • 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.

    -ScottA



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

    I can confirm that it is still buggy in R14.


Log in to reply