Re: Intersections

New Message Reply Date view Thread view Subject view Author view

Scott McMillan (scott++at++ht.com)
Thu, 28 Aug 1997 12:43:52 -0400 (EDT)


Didier Guzzoni wrote:
> Scott McMillan wrote:
> > I was successful in using multiple segs way back in 2.0 (no patches) but I
> > was allocating an array of 32 pfHit** even when I only had 4 or 5 segs.
> > Don't know if this has anything to do with my success, though.
>
> I am stuck trying to do the same, and it doesn't work. Let me show you
> what I do :
>
> pfHit **mHits[PFIS_MAX_SEGS];
> pfSegSet segSet;
>
> segSet.mode = PFTRAV_IS_PRIM;
> segSet.isectMask = 0xFFFFFFFF;
> segSet.activeMask = 0x03;
> segSet.userData = NULL;
> segSet.bound = NULL;
> segSet.discFunc = NULL;
>
> segSet.segs[...] = mySegs (Two of them, and there are OK)
>
> nbHits=(mRoot->isect(&segSet, (pfHit***)mHits))
> (Where mRoot is a pfNode pointing the whole scene)
>
> Even if I intersect the two segments, I get only (and always) one hit.
>
> My question is : Can I request the intersection query from the Root ?
> Shall I set some masks in the root itself (Using setTravMask)

I dusted off an old example in which I attach geometry I am interested in
contacting with to the scene, along with other stuff I am not interested in
testing intersections:

   const int CONTACT_GEOMETRY_MASK = 0x02; // arbitrarily set one bit

   // G_shared->anatomy is a pfNode *
   G_shared->anatomy = pfdLoadFile("hersheymod6.obj");

   // G_shared->scene is a pfScene *
   G_shared->scene->addChild(G_shared->anatomy);
   G_shared->anatomy->setTravMask(PFTRAV_ISECT, CONTACT_GEOMETRY_MASK,
                                  PFTRAV_SELF|PFTRAV_DESCEND,
                                  PF_SET);

For grins and giggles I also set the scene's isect traversal mask to
CONTACT_GEOMETRY_MASK, with no difference in behaviour. I suspect Performer
may be traversing the tree back to the root when I call setTravMask for the
anatomy node. If this is not the case, then you need to set the isect
traversal masks of all parent nodes to the OR'ed combination of all its
children's isect traversal mask. (I vaguely recall someone posting a
function that does this already, but I can't seem to find it at the moment).

Next I set up the intersection data structures. Since I have
NUM_CONTACT_POINTS isect segments and
                ((long) pow(2,NUM_CONTACT_POINTS)) - 1
is the corresponding bit field representation for setting the activeMask

   const int NUM_CONTACT_SEGMENTS = 4;
   pfHit **m_hits[PFIS_MAX_SEGS];
   pfSegSet m_contact_seg_set;

   m_contact_seg_set.mode = PFTRAV_IS_PRIM|PFTRAV_IS_CULL_BACK|PFTRAV_IS_NORM;
   m_contact_seg_set.activeMask = ((long) pow(2,NUM_CONTACT_POINTS)) - 1;
   m_contact_seg_set.discFunc = NULL;
   m_contact_seg_set.bound = NULL;
   m_contact_seg_set.isectMask = CONTACT_GEOMETRY_MASK;

All this can be set once. I was also successful when setting the isectMask
to 0xffffffff. I also ignore backfaces (PFTRAV_IS_CULL_BACK) but including
or omitting this has no effect on whether or not multiple isects are
detected. (Note: I am also asking for the normals, which again has no effect
on whether or not multiple hits are detected).

Now for each isect test, I need to define the isect segments themselves, and
for this I will use the pfSet::makePnts function (you can do whatever)

   pfVec3 pnt1[NUM_CONTACT_SEGMENTS], pnt2[NUM_CONTACT_SEGMENTS];

   // do something here to define the beginning and end of each contact
   // segment and store the results in pnt1[i] and pnt2[i] respectively.

   for (int i=0; i<NUM_CONTACT_SEGMENTS; i++)
   {
      m_contact_seg_set.segs[i].makePts(pt1, pt2);
   }

Then I check for contacts against the geometry (I have also tried isecting
against the scene with the same success):

   int num_hits = G_shared->anatomy->isect(&m_contact_seg_set, m_hits);

A possible culprit to your problems is your specification of the pfHit
argument. You shouldn't need the cast.

Now I need to process the pfHit info if num_hits is greater than 0;

   if (num_hits)
   {
      cerr << num_hits << ": ";

      for (i=0; i<NUM_CONTACT_POINTS; i++)
      {
         static int flags;
         m_hits[i][0]->query(PFQHIT_FLAGS, &flags);

         // Make sure point and normal are valid - you don't need the latter.
         if ((flags & PFHIT_POINT) && (flags & PFHIT_NORM))
         {
            // if we got here that means segment_i encountered a contact.
            cerr << i << ' ';

            static pfVec3 pnt, norm;
            m_hits[i][0]->query(PFQHIT_POINT, pnt.vec);
            m_hits[i][0]->query(PFQHIT_NORM, norm.vec);

            // if the object is attached via some DCS -- must Xform vectors
            // to express them in the global coordinate system.
            if (flags & PFHIT_XFORM)
            {
               static pfMatrix xform;

               m_hits[i][0]->query(PFQHIT_XFORM, (float*)xform.mat);
               pnt.xformPt(pnt, xform);
               norm.xformVec(norm, xform);
            }

            // do stuff with pnt and norm here to visualize results
         }
      }
      cerr << endl;
   }

I have line segment classes that were developed in-house which I use to debug
this stuff. I attach line segments to the scene which indicate where my
isect segs are and where the contact point is (if present) and aligned along
the normal direction at the intersection. I highly recommend you do
something like this to debug your intersection testing. You may find that
your intersection line segments aren't where they are supposed to be.

By the way this works under Performer 2.0 (with the latest patches) on an
Indigo2 Impact. I don't know about 2.1, but still works under 2.2beta.

Hope this helps,
scott

-- 
  Scott McMillan  |    HT Medical, Inc.   | Developing medical VE's
   scott++at++ht.com   |   http://www.ht.com   | surgical simulations
 Ph: 301-984-3706 |6001 Montrose Rd., #902| and surgery simulation
Fax: 301-984-2104 |  Rockville, MD 20852  | creation tools.
=======================================================================
List Archives, FAQ, FTP:  http://www.sgi.com/Technology/Performer/
            Submissions:  info-performer++at++sgi.com
        Admin. requests:  info-performer-request++at++sgi.com

New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:55:48 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.